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

Audio Discussion :

remplacer "memcpy" par "SDL_MixAudio" pour être capable de régler le volume audio


Sujet :

Audio

  1. #1
    Membre régulier Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Points : 114
    Points
    114
    Par défaut remplacer "memcpy" par "SDL_MixAudio" pour être capable de régler le volume audio
    Bonjour,

    Je souhaite être capable de régler le volume audio dans le logiciel Netgens [1] (un émulateur Megadrive).
    Donc, j'utilise la fonction SDL_MixAudio.
    J'ai juste à remplacer la fonction "memcpy" par la fonction "SDL_MixAudio" :
    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
    $ svn diff src/gens/sdllayer/g_sdlsound.c 
    Index: src/gens/sdllayer/g_sdlsound.c
    ===================================================================
    --- src/gens/sdllayer/g_sdlsound.c	(revision 9)
    +++ src/gens/sdllayer/g_sdlsound.c	(working copy)
    @@ -12,6 +12,7 @@
     #include "pcm.h"
     #include "misc.h"		// for Have_MMX flag
     #include "support.h"
    +#include "audio.h" /* for Audio_Volume */
     
     int Seg_To_Buffer = 8; // for frame skip
     int Seg_L[882], Seg_R[882];
    @@ -38,13 +39,16 @@
     {
       if (audio_len < (int) len)
         {
    -      memcpy (buffer, user, audio_len);
    +      /*memcpy (buffer, user, audio_len);*/
    +      SDL_MixAudio(buffer, user, audio_len, Audio_Volume);
           audio_len = 0;
           return;
         }
    -  memcpy (buffer, user, len);
    +  /*memcpy (buffer, user, len);*/
    +  SDL_MixAudio(buffer, user, len, Audio_Volume);
       audio_len -= len;
    -  memcpy (user, (unsigned char *) user + len, audio_len);
    +  /*memcpy (user, (unsigned char *) user + len, audio_len);*/
    +  SDL_MixAudio(user, (unsigned char *) user + len, audio_len, Audio_Volume);
     
     }
    Mais quand je fais ça, l'audio que j'entends n'est pas correct.
    J'ai lu [2] qui semble être un problème similaire.
    La solution est d'initialiser correctement le buffer audio en utilisant la fonction memset.
    Mais dans mon cas, le buffer semble être déjà correctement initialisé car la fonction memset est déjà utlisée quelque part dans ce fichier.
    Quoi qu'il en soit, si j'utilise le fonction memset avant les appels à SDL_MixAudio, alors je n'entends rien :
    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
    $ svn diff src/gens/sdllayer/g_sdlsound.c 
    Index: src/gens/sdllayer/g_sdlsound.c
    ===================================================================
    --- src/gens/sdllayer/g_sdlsound.c	(revision 9)
    +++ src/gens/sdllayer/g_sdlsound.c	(working copy)
    @@ -12,6 +12,7 @@
     #include "pcm.h"
     #include "misc.h"		// for Have_MMX flag
     #include "support.h"
    +#include "audio.h" /* for Audio_Volume */
     
     int Seg_To_Buffer = 8; // for frame skip
     int Seg_L[882], Seg_R[882];
    @@ -38,13 +39,19 @@
     {
       if (audio_len < (int) len)
         {
    -      memcpy (buffer, user, audio_len);
    +      /*memcpy (buffer, user, audio_len);*/
    +      memset(buffer, 0, audio_len);
    +      SDL_MixAudio(buffer, user, audio_len, Audio_Volume);
           audio_len = 0;
           return;
         }
    -  memcpy (buffer, user, len);
    +  /*memcpy (buffer, user, len);*/
    +  memset(buffer, 0, len);
    +  SDL_MixAudio(buffer, user, len, Audio_Volume);
       audio_len -= len;
    -  memcpy (user, (unsigned char *) user + len, audio_len);
    +  /*memcpy (user, (unsigned char *) user + len, audio_len);*/
    +  memset(user, 0, audio_len);
    +  SDL_MixAudio(user, (unsigned char *) user + len, audio_len, Audio_Volume);
     
     }
    Donc avez-vous une idée de comment je peux remplacer memcpy par SDL_MixAudio dans ce code pour être capable de régler le volume audio ? (et conserver un audio correct)

    Merci beaucoup.

    PS : j'ai déjà posé cette question sur le mailing-list de SDL [3] et à l'auteur de Gens (l'émulateur original) [4] mais aucune réponse...

    [1] http://sourceforge.net/projects/netgens/
    [2] http://forums.libsdl.org/viewtopic.p...c0b7fa9f45db36
    [3] http://lists.libsdl.org/pipermail/sd...ay/088327.html
    [4] https://www.youtube.com/user/stefda

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Il ne me semble pas logique de faire un memset pour mettre le buffer à 0, si c'est le buffer venant de SDL et contenant le son à jouer ?
    Après, vous avez donné des diff, ce qui rend un peu difficile la lecture/compréhension du code/contexte.

    Voici l'exemple de callback que j'utilise pour jouer du 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
    bool Sound :: play(Uint8 *pStream, int len)
    {
    	int amount = 0;
     
    	if (m_pSample == NULL )
    	{
    		return false;
    	}
     
    	if ( (m_pSample->length) == 0 )
    		return false;
     
     
    	if ( this->m_position >= m_pSample->length )
    	{
    		// Looping
    		if ( this->m_loop )
    		{
    			this->m_position = 0;
    		}
    		else // We are after the sound
    		{
    			return false;
    		}
    	}
     
    	// On regarde ce qui reste à jouer
    	amount = (m_pSample->length - this->m_position);
     
    	// Check 
    	if ( amount > len )
    		amount = len;
     
    	// Mixing sound
    	SDL_MixAudio(pStream, &m_pSample->pBuffer[this->m_position], amount, this->m_volume);
     
    	// Update of the position
    	this->m_position += amount;
     
    	return true;
    }
    (La SDL appelle cette fonction à chaque fois que du son doit être jouer.)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre régulier Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Points : 114
    Points
    114
    Par défaut
    Après, vous avez donné des diff, ce qui rend un peu difficile la lecture/compréhension du code/contexte.
    Le fichier source est ici :
    https://sourceforge.net/p/netgens/co...r/g_sdlsound.c

    Voici l'exemple de callback que j'utilise pour jouer du son :
    Merci je vais m'inspirer de ce code et essayer de faire quelque chose qui y ressemble.

    Mais d'après le man de SDL_AudioSpec, la fonction de callback n'est pas sensée avoir 3 paramètres ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef struct{
             int freq;
             Uint16 format;
             Uint8 channels;
             Uint8 silence;
             Uint16 samples;
             Uint32 size;
             void (*callback)(void *userdata, Uint8 *stream, int len);
             void *userdata;
           } SDL_AudioSpec;

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Dans mon cas, userdata n'est pas visible, car il me permet de passer un pointeur sur la classe d'où j'ai pris la fonction.
    Donc, oui, j'ai bien une fonction à trois paramètres, qui utilise le premier pour appeler cette version à deux paramètres. Donc c'est pareil
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre régulier Avatar de YuGiOhJCJ
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 206
    Points : 114
    Points
    114
    Par défaut
    C'est bon j'ai trouvé !

    La solution était ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void proc (void *user, Uint8 * buffer, int len)
    {
      if (audio_len < (int) len)
        {
          memcpy (buffer, user, audio_len);
          audio_len = 0;
          return;
        }
      /*memcpy (buffer, user, len);*/
      SDL_MixAudio(buffer, user, len, Audio_Volume);
      audio_len -= len;
      memcpy (user, (unsigned char *) user + len, audio_len);
     
    }
    Problème résolu

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/02/2014, 10h24

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