IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

[son]paramètre "len" de la fonction callback.


Sujet :

SDL

  1. #1
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut [son]paramètre "len" de la fonction callback.
    Bonjour

    je cherche désespérément une information sur le paramètre len de la fonction callback utilisée pour générer du son.

    Je cherche, non pas un exemple, mais l'explication de tout ce qui se passe dans cette fonction callback ! Je commence à m'en faire une idée. Mais, j'aimerai trouver une information claire.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Bon je vais mettre un code à la fin de ce post qui fonctionne pour moi. http://www.libsdl.org/intro.en/usingsound.html est la page de référence que j'ai utilisé.

    Pour répondre à ta question, le callback a pour définition :

    - Premier argument : ce que l'utilisateur veut.
    - Deuxième argument: le stream dans lequel mettre le son qu'on voudra
    - Len -> la taille du buffer stream

    Donc normalement, on va tenter de copier au max len octets vers stream via SDL_MixAudio mais ce n'est pas obligatoire...

    Ensuite, j'ai pris ton code et j'ai joué avec... il est un peu moche tout de même. Voici ton code modifié:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <SDL.h>
    #include <SDL_ttf.h>
    #include <SDL/SDL_image.h>
    #include <SDL_mixer.h>
    #include <SDL_sound.h>
     
     
    void audioCallBack(void *udata, Uint8 *stream, int len);
     
     
    /* http://loka.developpez.com/tutoriel/sdl */
     typedef struct sUserData
    {
        Uint32* audioLen;
        Uint32* audioPos;
        Uint32* audioSize;
        Uint8 *audioBuffer;
    }SUserData;
     
    int main ( int argc, char** argv )
    {
        SDL_Surface* screen;
        SDL_Surface *message = NULL;
        SDL_Surface* bmp;
        SDL_Rect dstrect;
        unsigned short i=0;
        int done = 0;
        char ch[20];
        TTF_Font *font;
        SDL_Event event;
        SDL_Color textColor = { 255, 255, 255 };
        SDL_AudioSpec audioSortie,audioExacte;
        SDL_AudioSpec audioBufferSpec;
        Uint8 *audioBuffer;
        Uint32 audioBufferLen;
        Uint32 audioLen, audioPos;
        SUserData *userData;
        SDL_AudioCVT cvt;
     
     
        // initialize SDL video
        if ( SDL_Init( SDL_INIT_VIDEO  | SDL_INIT_AUDIO) < 0 )
        {  /*   pour l'image                pour le son   */
            printf( "Unable to init SDL: %s\n", SDL_GetError() );
            return 1;
        }
     
        // make sure SDL cleans up before exit
        atexit(SDL_Quit);
     
        // Définition des propriétés audio
        audioSortie.freq = 22050;
        audioSortie.format = AUDIO_S16;
        audioSortie.channels = 2;
        audioSortie.samples = 1024;
        audioSortie.callback =audioCallBack;
     
        userData = malloc (sizeof (*userData));
        audioSortie.userdata = userData;
     
        // Initialisation de la couche audio
        if (SDL_OpenAudio(&audioSortie, &audioExacte) < 0)
        {
            fprintf(stderr, "Erreur d'ouverture audio: %s\n", SDL_GetError());
            return (-1);
        }
     
        // A inclure dans votre code pour charger un fichier sonore dans audioBuffer
        if(!SDL_LoadWAV("test_son1/high.wav", &audioBufferSpec, &audioBuffer, &audioBufferLen))
        {
            printf("Erreur lors du chargement du fichier WAV.\n");
            fprintf (stderr, "%s\n", SDL_GetError ());
            return 1;
        }
     
        SDL_BuildAudioCVT(&cvt, audioBufferSpec.format, audioBufferSpec.channels, audioBufferSpec.freq, AUDIO_S16,   2, 22050);
        cvt.buf = malloc(audioBufferLen*cvt.len_mult);
        memcpy(cvt.buf, audioBuffer, audioBufferLen);
        cvt.len = audioBufferLen;
        SDL_ConvertAudio(&cvt);
        SDL_FreeWAV(audioBuffer);
     
        userData->audioLen = &audioLen;
        userData->audioPos = &audioPos;
        userData->audioSize = &audioBufferLen;
        fprintf (stderr , "%p\n", audioBuffer);
        userData->audioBuffer = audioBuffer;
     
        printf("Propriétés du fichier audio %d : %d canaux, %d fréquence %d octets.\n",
     	audioBufferSpec.format & 0xff, audioBufferSpec.channels, audioBufferSpec.freq, audioBufferLen);
     
        // Lancement de la lecture
        SDL_PauseAudio(0);
        // Attendre que la lecture du son soit terminée
        audioLen=audioBufferLen;
        while ( audioLen > 0 )
        {
            SDL_Delay(100);
        }
     
        // Fermeture du module
        SDL_CloseAudio();
        return 0;
     
    }
     
    void audioCallBack(void *udata, Uint8 *stream, int len)
    {
        SUserData *user = udata;
        printf ("Here data %d %d %d - %d\n", 
                *(user->audioLen),
                *(user->audioPos),
                *(user->audioSize),
                len);
        Uint32 *audioLen = user->audioLen;
        Uint32 *audioPos = user->audioPos;
        Uint32 *audioSize = user->audioSize;
     
        // On ne lit que s'il reste des données à jouer
        if ( *audioLen == 0 )
            return;
     
        // Remise à zéro du tampon de sortie
        memset(stream, 0, len);
        fprintf (stderr , "%p\n", user->audioBuffer);
     
        // Lecture du buffer audio
        if (*audioPos < *audioSize) {
            if (*audioPos + len > *audioSize)
            {
                len = *audioSize - *audioPos;
            }
     
            SDL_MixAudio(stream, user->audioBuffer + *audioPos, len, SDL_MIX_MAXVOLUME);
     
            *audioPos += len;
        }
     
        // Décrémentation de ce qu'il reste à lire
        if (*audioLen > len)
         *audioLen -= len;
        else
         *audioLen = 0;
    }
    Par contre, chez moi ca ne marchait pas puisqu'il fallait mettre la bonne fréquence audio. Ca marche mieux avec le code ci-dessous...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <SDL.h>
    #include <SDL_ttf.h>
    #include <SDL/SDL_image.h>
    #include <SDL_mixer.h>
    #include <SDL_sound.h>
     
    #define NUM_SOUNDS 2
    struct sample {
        Uint8 *data;
        Uint32 dpos;
        Uint32 dlen;
    } sounds[NUM_SOUNDS];
     
    void mixaudio(void *unused, Uint8 *stream, int len)
    {
        int i;
        Uint32 amount;
     
        for ( i=0; i<NUM_SOUNDS; ++i ) {
            amount = (sounds[i].dlen-sounds[i].dpos);
            if ( amount > len ) {
                amount = len;
            }
            SDL_MixAudio(stream, &sounds[i].data[sounds[i].dpos], amount, SDL_MIX_MAXVOLUME);
            sounds[i].dpos += amount;
        }
    }
     
    void PlaySound(char *file)
    {
        int index;
        SDL_AudioSpec wave;
        Uint8 *data;
        Uint32 dlen;
        SDL_AudioCVT cvt;
     
        /* Look for an empty (or finished) sound slot */
        for ( index=0; index<NUM_SOUNDS; ++index ) {
            if ( sounds[index].dpos == sounds[index].dlen ) {
                break;
            }
        }
        if ( index == NUM_SOUNDS )
            return;
     
        /* Load the sound file and convert it to 16-bit stereo at 22kHz */
        if ( SDL_LoadWAV(file, &wave, &data, &dlen) == NULL ) {
            fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
            return;
        }
        SDL_BuildAudioCVT(&cvt, wave.format, wave.channels, wave.freq,
                                AUDIO_S16,   2,             22050);
        cvt.buf = malloc(dlen*cvt.len_mult);
        memcpy(cvt.buf, data, dlen);
        cvt.len = dlen;
        SDL_ConvertAudio(&cvt);
        SDL_FreeWAV(data);
     
        /* Put the sound data in the slot (it starts playing immediately) */
        if ( sounds[index].data ) {
            free(sounds[index].data);
        }
     
        SDL_LockAudio();
        sounds[index].data = cvt.buf;
        sounds[index].dlen = cvt.len_cvt;
        sounds[index].dpos = 0;
        SDL_UnlockAudio();
    }
     
    int finishedSounds (void)
    {
        int i;
        /* Look for an empty (or finished) sound slot */
        for (i=0; i < NUM_SOUNDS; i++ ) {
            if ( sounds[i].dpos != sounds[i].dlen ) {
                break;
            }
        }
     
        if ( i == NUM_SOUNDS )
            return 1;
     
        return 0;
    }
     
    int main (void)
    {
        SDL_AudioSpec audioSortie,audioExacte;
        SDL_AudioSpec audioBufferSpec;
        // initialize SDL video
        if ( SDL_Init( SDL_INIT_VIDEO  | SDL_INIT_AUDIO) < 0 )
        {  /*   pour l'image                pour le son   */
            printf( "Unable to init SDL: %s\n", SDL_GetError() );
            return 1;
        }
     
        // make sure SDL cleans up before exit
        atexit(SDL_Quit);
     
        // Définition des propriétés audio
        audioSortie.freq = 22050;
        audioSortie.format = AUDIO_S16;
        audioSortie.channels = 2;
        audioSortie.samples = 1024;
        audioSortie.callback = mixaudio;
     
        // Initialisation de la couche audio
        if (SDL_OpenAudio(&audioSortie, &audioExacte) < 0)
        {
            fprintf(stderr, "Erreur d'ouverture audio: %s\n", SDL_GetError());
            return (-1);
        }
     
        PlaySound("test_son1/high.wav");
     
        SDL_PauseAudio (0);
     
        while (!finishedSounds ()) 
            ;
        SDL_CloseAudio ();
        return 0;
    }
    Finalement, es-tu sûr de vouloir passer par là? SDL_mixer est déjà mieux et ensuite y a nettement mieux que directement SDL_sound...
    Jc

  3. #3
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut
    J'ai eu une idée en regardant les enfants faire de la luge. En rentrant, j'ai testé et j'ai entendu un son.
    Après, je regarde ce que tu as écrit hier soir (je n'ai pas eu le temps depuis hier soir de regarder).

    Je vois que nous avons eu le même problème de fréquence. Moi, j'en suis là. Je vois que tu as fais une conversion, mais moi, cette idée ne me convient pas car je veux comprendre pour quoi mon son qui est à la même fréquence que celle définie pour le système de son 44100 est deux fois plus grave (ou lent) que l'original. le son de l'orage une octave en dessous, ça donne ! On dirait une symbale

    Pour ce qui est de la structure que tu utilises, c'était le point suivant que je comptais essayer. Je pensais à la même chose. Mon but, avec cette structure serait surtout de supprimer toutes variables globales : je n'aime pas ça du tout ! Donc, de la mettre en paramètre en userdata.

    Les autres points que tu abordes :
    1) mon code ? J'ai donné mon code où ? Pas dans ce fil au moins Je pourrais le donner quand j'aurais compris, et qu'il sera bien commenté, mais pas avant
    2) Pourquoi SDL_sound et pas autre chose ? Parce que mon but est de comprendre SDL. Le son comme le reste. Il n'y aurait pas eu de son dans SDL, je n'aurais pas essayé d'en faire. Il y en a, je veux le comprendre.

    Pour le moment, je veux donc comprendre le pourquoi du comment de cette octave ! Je penserais à un wav avec gauche et droit codé en parallèle et que j'envoie tout comme si c'est du mono. Mais, j'ai bien mis channels à 2 ! Et en plus, SDL me signal que mon son est sur un seul canal. Si c'est ce que je pense, je devrais avoir une octave en trop dans ce cas. Et là, j'en manque une au contraire

    Pour info :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <SDL.h>
    #include <SDL_ttf.h>
    #include <SDL/SDL_image.h>
    #include <SDL_mixer.h>
    #include <SDL_sound.h>
     
     
    void charge_tampon(void *udata, Uint8 *stream, int len);
     
     
    /* http://loka.developpez.com/tutoriel/sdl */
     
    int main ( int argc, char** argv )
    {
    [...]
        // audio
        SDL_AudioSpec desire,obtenu,soundfile;
        void * data_musique[4];
        Uint8 *audioBuffer;
        Uint32 audioBufferLen;
        Uint32 audioPos=0;
     
        // initialize SDL video
        if ( SDL_Init( SDL_INIT_VIDEO  | SDL_INIT_AUDIO) < 0 )
        {  /*   pour l'image                pour le son   */
            printf( "Unable to init SDL: %s\n", SDL_GetError() );
            return 1;
        }
     
        // make sure SDL cleans up before exit
        atexit(SDL_Quit);
     
        // Initialisation de l'audio
        desire.freq=44100;
        desire.format=AUDIO_S16LSB;
        desire.channels=2;
        desire.samples=2048;
        desire.callback=charge_tampon;
        desire.userdata=data_musique;
        data_musique[0]=(void *)&obtenu;
        data_musique[1]=(void *)&audioBuffer;
        data_musique[2]=(void *)&audioPos;
        data_musique[3]=(void *)&audioBufferLen;
        SDL_OpenAudio(&desire, &obtenu);
        printf("Résultat du chargement du son :\n----------+----------+----------\nParamètre | Demandé  | Récupéré \n");
        printf("----------+----------+----------\n");
        printf("fréquence |%9d |%9d\n",desire.freq,obtenu.freq);
        printf("----------+----------+----------\n");
        printf("format    |%9hu |%9hu\n",desire.format,obtenu.format);
        printf("----------+----------+----------\n");
        printf("canaux    |%9hu |%9hu\n",desire.channels,obtenu.channels);
        printf("----------+----------+----------\n");
        printf("tail tamp |%9hu |%9hu\n",desire.samples,obtenu.samples);
        printf("----------+----------+----------\n");
     
        if (!SDL_LoadWAV("son/orage.wav", &soundfile, &audioBuffer, &audioBufferLen))
        {
            printf("Erreur lors du chargement du fichier WAV.\n");
        }
        printf("\nPropriétés du fichier %d audio: %d canaux, %d fréquence %d octets.\n", soundfile.format & 0xff, soundfile.channels, soundfile.freq, audioBufferLen);
        // Le son ne sera pas joué tant que vous n'aurez pas appelé SDL_PauseAudio(0), vous permettant d'exécuter d'autres initialisations audio avant que votre fonction de rappel ne soit exécutée
        SDL_PauseAudio(0);
        // SDL_PauseAudio() est la fonction servant à mettre ou à enlever la pause. En effet, de base le son est sur pause, passer 0 en argument à cette fonction relance la lecture, 1 réenclenchant la pause.
     
    [...]
     
       SDL_CloseAudio();
        printf("Exited cleanly\n");
        return 0;
    }
     
     
     
     
    void charge_tampon(void *udata, Uint8 *stream, int len)
    {
        // paramètres à avoir : position actuelle dans le buffer, fin du buffer
        if ((*((Uint32 **)udata)[2]+((SDL_AudioSpec **)udata)[0]->samples)<*((Uint32 **)udata)[3])
        {
        SDL_MixAudio(stream, *((Uint8 ***)udata)[1]+ *((Uint32 **)udata)[2], len, .1*SDL_MIX_MAXVOLUME);
         *((Uint32 **)udata)[2]+=((SDL_AudioSpec **)udata)[0]->samples;
        }
        else
        {
         SDL_MixAudio(stream, *((Uint8 ***)udata)[1]+ *((Uint32 **)udata)[2],*((Uint32 **)udata)[3]- *((Uint32 **)udata)[2] , SDL_MIX_MAXVOLUME);
         *((Uint32 **)udata)[2]=0;
        }
    }
    Citation Envoyé par la sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Résultat du chargement du son :
    ----------+----------+----------
    Paramètre | Demandé  | Récupéré
    ----------+----------+----------
    fréquence |    44100 |    44100
    ----------+----------+----------
    format    |    32784 |    32784
    ----------+----------+----------
    canaux    |        1 |        1
    ----------+----------+----------
    tail tamp |     1024 |     1024
    ----------+----------+----------
     
    Propriétés du fichier 16 audio: 1 canaux, 44100 fréquence 299520 octets.
    Exited cleanly
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  4. #4
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut
    Je n'avais pas vu : http://jeux.developpez.com/faq/sdl/?...AUDIO_callback !
    Il répond à ma première question. Par contre, il n'explique pas pouquoi mon son est mal joué. Audacious (mon lecteur de musique) l'interprête bien !
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  5. #5
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut
    Pensant à un problème de mon fichier wav, je suis allé en chercher un autre et j'ai trouvé : http://pagesperso-orange.fr/jean-lou...e_son_wav.html http://pagesperso-orange.fr/jean-lou...e_son_wav.html
    j'ai pris roulement-tambour.wav ou rire-enfants.wav et j'ai le même problème. À force de chercher, je me demande si ce n'est pas un problème plus important. J'ai encore un son "métallique". Pour être sûr du bon format, j'ai même rajouté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        if (!SDL_LoadWAV("son/rire-enfants.wav", &soundfile, &audioBuffer, &audioBufferLen))
        {
            printf("Erreur lors du chargement du fichier WAV.\n");
        }
        printf("\nPropriétés du fichier %d audio: %d canaux, %d fréquence %d octets.\n", soundfile.format & 0xff, soundfile.channels, soundfile.freq, audioBufferLen);
        // Le son ne sera pas joué tant que vous n'aurez pas appelé SDL_PauseAudio(0), vous permettant d'exécuter d'autres initialisations audio avant que votre fonction de rappel ne soit exécutée
        SDL_BuildAudioCVT(&cvt, soundfile.format, soundfile.channels, soundfile.freq,obtenu.format,obtenu.channels,obtenu.freq);
        cvt.buf =(Uint8 *)malloc(audioBufferLen*cvt.len_mult);
        memcpy(cvt.buf, audioBuffer, audioBufferLen);
        cvt.len = audioBufferLen;
        SDL_ConvertAudio(&cvt);
        SDL_FreeWAV(audioBuffer);
        audioBuffer=cvt.buf;
        data_musique[0]=(void *)&obtenu;
        data_musique[1]=(void *)&audioBuffer;
        data_musique[2]=(void *)&audioPos;
        data_musique[3]=(void *)&audioBufferLen;
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  6. #6
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut
    Bonjour

    je viens de résoudre mon problème !
    J'avais remplacé dans la fonction callback le dernier paramètre (len) par obtenu.sample.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  7. #7
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 607
    Par défaut
    Je suis arrivé à faire ce que je souhaitais !
    Une infinité de son....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <SDL.h>
    #include <SDL_ttf.h>
    #include <SDL/SDL_image.h>
    #include <SDL_mixer.h>
    #include <SDL_sound.h>
     
    struct param
    {
        Uint32 audioBufferLen;
        Uint32 audioPos;
        SDL_AudioCVT cvt;
        struct param * suiv;
        struct param * prec;
    };
     
     
     
    void charge_tampon(void * udata, Uint8 *stream, int len);
    int place_musique(struct param ** data_musique,char const * adresse,SDL_AudioSpec * obtenu);
     
    /* http://loka.developpez.com/tutoriel/sdl */
     
    int main ( int argc, char** argv )
    {
        SDL_Surface* screen;
        SDL_Surface *message = NULL;
        SDL_Surface* bmp;
        SDL_Rect dstrect;
        unsigned short i=0;
        bool done = false;
        char ch[20];
        TTF_Font *font;
        SDL_Event event;
        SDL_Color textColor = { 255, 255, 255 };
        // audio
        SDL_AudioSpec desire,obtenu;
        struct param * data_musique=NULL;
     
        // initialize SDL video
        if ( SDL_Init( SDL_INIT_VIDEO  | SDL_INIT_AUDIO) < 0 )
        {  /*   pour l'image                pour le son   */
            printf( "Unable to init SDL: %s\n", SDL_GetError() );
            return 1;
        }
     
        // make sure SDL cleans up before exit
        atexit(SDL_Quit);
     
        // Initialisation de l'audio
        desire.freq=11025;
        desire.format=AUDIO_S16;
        desire.channels=2;
        desire.samples=2048;
        desire.callback=charge_tampon;
        desire.userdata=&data_musique;
        SDL_OpenAudio(&desire, &obtenu);
        printf("Résultat du chargement du son :\n----------+----------+----------\nParamètre | Demandé  | Récupéré \n");
        printf("----------+----------+----------\n");
        printf("fréquence |%9d |%9d\n",desire.freq,obtenu.freq);
        printf("----------+----------+----------\n");
        printf("format    |%9hX |%9hX\n",desire.format,obtenu.format);
        printf("----------+----------+----------\n");
        printf("canaux    |%9hu |%9hu\n",desire.channels,obtenu.channels);
        printf("----------+----------+----------\n");
        printf("tail tamp |%9hu |%9hu\n",desire.samples,obtenu.samples);
        printf("----------+----------+----------\n");
     
        place_musique(&data_musique,"son/rire-enfants.wav",&obtenu);
     
        // create a new window
        screen = SDL_SetVideoMode(640, 480, 16, 		SDL_HWSURFACE|SDL_DOUBLEBUF | SDL_RESIZABLE);
        if (!screen)
        {
            printf("Unable to set 640x480 video: %s\n", SDL_GetError());
            return 1;
        }
     
        // load an image
        //bmp = SDL_LoadBMP("cb.bmp");
        bmp = IMG_Load("images/saint_manchot.png");
        if (!bmp)
        {
            printf("Unable to load bitmap: %s\n", SDL_GetError());
            return 1;
        }
     
     
    	//Initialisation de SDL_TTF
    	if( TTF_Init() == -1 )
    	{
    		return false;
    	}
     
        //Ouverture du Font
    	font = TTF_OpenFont( "/home/bs/.font/a010013l.ttf", 28 );
    	//S'il y a une erreur dans le chargement du Font
    	if( font == NULL )
    	{
    	    printf("Erreur de chargement de la font\n");
    		return false;
    	}
        //Mise en place du texte sur la surface message
        message = TTF_RenderText_Solid( font, "Test pour sdl_ttf", textColor );
        //S'il y a une erreur dans la mise en place du texte
        if( message == NULL )
        {
            return 1;
        }
     
     
     
     
     
        // centre the bitmap on screen
        //SDL_Rect dstrect;
        //dstrect.x = (screen->w - bmp->w) / 2;
        //dstrect.y = (screen->h - bmp->h) / 2;
        dstrect.x =0;
        dstrect.y =0;
     
    // program main loop
        while (!done)
        {
            // Tant qu'il y a un événement à traiter
            dstrect.x =i%(screen->w - bmp->w);
            dstrect.y =i%(screen->h - bmp->h);
            while (SDL_PollEvent(&event))
            {
                // check for messages
                switch (event.type) // voir /usr/include/SDL/SDL_events.h
                {
                    // exit if the window is closed
                case SDL_QUIT:
                    done = true;
                    break;
     
                    // check for keypresses
                case SDL_KEYDOWN: // voir /usr/include/SDL/SDL_keysym.h
                        // exit if ESCAPE is pressed
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                            done = true;
                        else if (event.key.keysym.sym == 'r')
                            place_musique(&data_musique,"son/rire-enfants.wav",&obtenu);
                        else if (event.key.keysym.sym == SDLK_a) // 'a'
                            place_musique(&data_musique,"son/alarme.wav",&obtenu);
                        else if (event.key.keysym.sym == 'o')
                            place_musique(&data_musique,"son/orage.wav",&obtenu);
                        break;
                case SDL_MOUSEMOTION:
                        dstrect.x =event.motion.x;
                        dstrect.y =event.motion.y;
                        break;
                case SDL_VIDEORESIZE : // changement de taille
                        screen = SDL_SetVideoMode( event.resize.w, event.resize.h,16, SDL_HWSURFACE|SDL_DOUBLEBUF | SDL_RESIZABLE);
                        break;
     
                } // end switch
            } // end of message processing
     
            // DRAWING STARTS HERE
     
            // clear screen
            if (i==0)
             SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
     
            // draw bitmap
            SDL_BlitSurface(bmp, 0, screen, &dstrect);
            textColor.r=(65536-i)%256;
            textColor.g=i%256;
            textColor.b=(3*i)%255;
            message = TTF_RenderText_Solid( font, "Test pour sdl_ttf", textColor );
            dstrect.x =(4*i)%(screen->w - message->w);
            dstrect.y =(4*i)%(screen->h - message->h);
            SDL_BlitSurface(message, 0, screen, &dstrect);
            if (i%256==0)
            {
             sprintf(ch,"%hu",i>>8);
             SDL_WM_SetCaption( ch, NULL );
            }
            i++;
     
            // DRAWING ENDS HERE
     
            // finally, update the screen :)
            SDL_Flip(screen);
        } // end main loop
     
        // free loaded bitmap
        SDL_FreeSurface(bmp);
     
        // all is well ;)
        // Vous dévez refermer le contexte après son utilisation par
        SDL_CloseAudio();
        printf("Exited cleanly\n");
        return 0;
    }
     
     
     
     
    void charge_tampon(void * udatat, Uint8 *stream, int len)
    {
        struct param * udata, * fdata;
        udata=*((struct param **)udatat); /* simplification de l'écriture */
     
        while(udata!=NULL)
        {
                if ((udata->audioPos+len)<udata->audioBufferLen)
                {
                    SDL_MixAudio(stream, udata->cvt.buf+ udata->audioPos, len, SDL_MIX_MAXVOLUME);
                    udata->audioPos+=len;
                    udata=udata->suiv;
                }
                else
                {
                    SDL_MixAudio(stream, udata->cvt.buf+ udata->audioPos,udata->audioBufferLen-udata->audioPos , SDL_MIX_MAXVOLUME);
                    /* j'enlève l'élément dans la chaine */
                    if (udata->prec!=NULL)
                     udata->prec->suiv=udata->suiv;
                    else
                     *((struct param **)udatat)=udata->suiv;
                    if (udata->suiv!=NULL)
                     udata->suiv->prec=udata->prec;
                    fdata=udata->suiv;
                    free(udata);
                    udata=fdata;
                }
        }
    }
     
     
    int place_musique(struct param ** data_musique,char const * adresse,SDL_AudioSpec * obtenu)
    {
        struct param * tmp_data_musique;
        Uint8 *audioBuffer;
        SDL_AudioSpec soundfile;
     
     
        SDL_PauseAudio(1);
        // Le son ne sera pas joué tant que vous n'aurez pas appelé SDL_PauseAudio(0), vous permettant d'exécuter d'autres initialisations audio avant que votre fonction de rappel ne soit exécutée
        tmp_data_musique=(struct param *)malloc(sizeof(struct param));
        tmp_data_musique->suiv=*data_musique;
        tmp_data_musique->prec=NULL;
        if (*data_musique!=NULL)
         (*data_musique)->prec=tmp_data_musique;
        *data_musique=tmp_data_musique;
        (*data_musique)->prec=NULL;
        if (!SDL_LoadWAV(adresse, &soundfile, &(audioBuffer), &((*data_musique)->audioBufferLen)))
        {
            printf("Erreur lors du chargement du fichier %s.\n",adresse);
            return 0;
        }
        //printf("\nPropriétés du fichier %d audio: %d canaux, %d fréquence %d octets.\n", soundfile.format & 0xff, soundfile.channels, soundfile.freq, data_musique->audioBufferLen);
        SDL_BuildAudioCVT(&(tmp_data_musique->cvt), soundfile.format, soundfile.channels, soundfile.freq,obtenu->format,obtenu->channels,obtenu->freq);
        tmp_data_musique->cvt.buf =(Uint8 *)malloc(tmp_data_musique->audioBufferLen*tmp_data_musique->cvt.len_mult);
        memcpy(tmp_data_musique->cvt.buf, audioBuffer, tmp_data_musique->audioBufferLen);
        tmp_data_musique->cvt.len = tmp_data_musique->audioBufferLen;
        SDL_ConvertAudio(&(tmp_data_musique->cvt));
        SDL_FreeWAV(audioBuffer);
        tmp_data_musique->audioPos=0;
     
        SDL_PauseAudio(0);
        return 1;
    }
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo