Windows, c++ et wav

Windows, c++ et wav - Programmation

Marsh Posté le 12-11-2001 à 22:41:57    

J'aimerais savoir comment on fait pour jouer un fichier wav. J'ai regardé whotsit.org, g trouvé ce que cherchais mais je comprend pas énormément de trucs vu que c'est assez énorme. En plus y'a juste le format et pas le code en c++ pour le lire... Ouais faut pas rêver...
Mais j'aimerais bien pouvoir faire ça et vu que c'est pas une priorité, j'aimerais bien ne pas avoir à me casser le cerveau en 2...
Merci

Reply

Marsh Posté le 12-11-2001 à 22:41:57   

Reply

Marsh Posté le 13-11-2001 à 01:36:41    

Adapté depuis des routines de gdmag :
 
PlayWav.h
 

Code :
  1. // PlayWav.h
  2. // Utilisation :
  3. // CloseSound()
  4. // InitSound(hwnd)
  5. // int wavnum= LoadWav("c:\son.wav" )
  6. // ...
  7. // et dans ta boucle principale : PlayWav(wavnum)
  8. #include <Win32Headers++.pch++>
  9. #include <windows.h>
  10. bool InitSound(HWND hwnd);
  11. int LoadWav(char * name);
  12. void PlayWav(int nsnd);
  13. void CloseSound();


 
 
 
 
 
 
 
PlayWav.cpp
 

Code :
  1. // PlayWav.cpp
  2. #include <dsound.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <malloc.h>
  7. #include "PlayWav.h"
  8. LPDIRECTSOUND lpDS;
  9. const int MaxStreams=32; // voies disponibles
  10. const int MaxSounds=512;     // sons charges en memoire  
  11. static bool IsAvailable=false;
  12. HRESULT CreatDSBuffer(LPDIRECTSOUND lpDS, LPDIRECTSOUNDBUFFER * lplpDSB, DWORD SoundBytes,
  13.      DWORD frequence, int isStereo, int is16bit);
  14. HRESULT CreatDSBuffer(LPDIRECTSOUND lpDS, LPDIRECTSOUNDBUFFER * lplpDSB, DWORD SoundBytes,
  15.      DWORD frequence, int isStereo, int is16bit)
  16. {
  17. DSBUFFERDESC dsbd;
  18. PCMWAVEFORMAT fmt;
  19. fmt.wf.nChannels=(isStereo)?2:1;
  20. fmt.wBitsPerSample=(is16bit)?16:8;
  21. fmt.wf.nSamplesPerSec=frequence;
  22. fmt.wf.nBlockAlign=fmt.wf.nChannels*(fmt.wBitsPerSample>>3);
  23. fmt.wf.nAvgBytesPerSec=fmt.wf.nSamplesPerSec*fmt.wf.nBlockAlign;
  24. fmt.wf.wFormatTag=WAVE_FORMAT_PCM;
  25. memset(&dsbd, 0, sizeof(dsbd));
  26. dsbd.lpwfxFormat=(LPWAVEFORMATEX)&fmt;
  27. dsbd.dwSize=sizeof(DSBUFFERDESC);
  28. dsbd.dwBufferBytes=SoundBytes;
  29. dsbd.dwFlags=0;
  30. return (lpDS->CreateSoundBuffer(&dsbd, lplpDSB, 0));
  31. }
  32. HRESULT LoadSoundData(LPDIRECTSOUNDBUFFER lpDSB, char * SoundDataPtr, DWORD TotalBytes);
  33. HRESULT LoadSoundData(LPDIRECTSOUNDBUFFER lpDSB, char * SoundDataPtr, DWORD TotalBytes)
  34. {
  35. LPVOID ptr1,ptr2;
  36. DWORD len1,len2;
  37. HRESULT result;
  38. TryLockAgainLabel:
  39. result=lpDSB->Lock(0,TotalBytes, &ptr1, &len1, &ptr2, & len2, 0);
  40. switch(result)
  41. {
  42.  case DS_OK:
  43.   memcpy(ptr1, SoundDataPtr, len1);
  44.   if(ptr2)
  45.    memcpy(ptr2, SoundDataPtr+len1, len2);
  46.   lpDSB->Unlock(ptr1, len1, ptr2, len2);
  47.   break;
  48.  case DSERR_BUFFERLOST:
  49.   result=lpDSB->Restore();
  50.   if (result==DS_OK)
  51.    goto TryLockAgainLabel ;
  52.   break;
  53. }
  54. return result;
  55. }
  56. typedef struct DSSTREAMTAG
  57. {
  58. int Playing, PleaseClose;
  59. char * CurrentPosition;
  60. DWORD BytesLeft, NoCallbacks, HalfBufferPoint, LastHalf;
  61. int CloseOnNext;
  62. LPDIRECTSOUNDBUFFER lpDSB;
  63. char SilenceByte;
  64. } DSSTREAM;
  65. static void StreamCopy(DSSTREAM * s, char * ptr, DWORD len)
  66. {
  67. DWORD amt;
  68. amt=(len>s->BytesLeft)?s->BytesLeft:len;
  69. if (amt)
  70. {
  71.  memcpy(ptr,s->CurrentPosition, amt);
  72.  s->CurrentPosition+=amt;
  73.  s->BytesLeft-=amt;
  74. }
  75. len-=amt;
  76. if(len)
  77. {
  78.  memset(ptr+amt, s->SilenceByte, len);
  79.  s->CloseOnNext=1;
  80. }
  81. }
  82. static void StreamFillAHalf(DSSTREAM * s, DWORD Half)
  83. {
  84. char* ptr1, *ptr2;
  85. DWORD len1,len2;
  86. TryLockAgainLabel:
  87. switch(s->lpDSB->Lock(Half,s->HalfBufferPoint, &ptr1, &len1, &ptr2, & len2, 0))
  88. {
  89.  case DS_OK:
  90.   StreamCopy(s, ptr1, len1);
  91.   if(ptr2)
  92.    StreamCopy(s, ptr2, len2);
  93.   s->lpDSB->Unlock(ptr1, len1, ptr2, len2);
  94.   break;
  95.  case DSERR_BUFFERLOST:
  96.   if (s->lpDSB->Restore()==DS_OK)
  97.    goto TryLockAgainLabel ;
  98.   break;
  99. }
  100. }
  101. static void CALLBACK StreamTimer(UINT id, UINT msg, DWORD user, DWORD dw1, DWORD dw2)
  102. {
  103. DWORD playp, writep;
  104. DWORD WhichHalf;
  105. DSSTREAM * s=(DSSTREAM*)user;
  106. if(s->NoCallbacks++==0)
  107. {
  108.  if(s->PleaseClose)
  109.  {
  110.  ShutDownStreamingLabel:
  111.   timeKillEvent(id);
  112.   timeEndPeriod(62);
  113.   s->lpDSB->Stop();
  114.   s->lpDSB->Release();
  115.   s->Playing=0;
  116.   return;
  117.  }
  118.  s->lpDSB->GetCurrentPosition(& playp, &writep);
  119.  WhichHalf=(playp<s->HalfBufferPoint)?0:s->HalfBu
  120. fferPoint;
  121.  if(WhichHalf!=s->LastHalf)
  122.  {
  123.   if(s->CloseOnNext)
  124.    goto ShutDownStreamingLabel;
  125.   StreamFillAHalf(s, s->LastHalf);
  126.   s->LastHalf= WhichHalf;
  127.  }
  128. }
  129. s->NoCallbacks--;
  130. }
  131. void StartStreaming(DSSTREAM * s, void * addr, DWORD len, LPDIRECTSOUND lpDS, LPWAVEFORMATEX format);
  132. void StartStreaming(DSSTREAM * s, void * addr, DWORD len, LPDIRECTSOUND lpDS, LPWAVEFORMATEX format)
  133. {
  134. DSBUFFERDESC dsbd;
  135. if (s)
  136. {
  137.  memset(s, 0, sizeof(DSSTREAM));
  138.  if((addr)&&(lpDS)&&(format))
  139.  {
  140.   memset(&dsbd, 0, sizeof(dsbd));
  141.   dsbd.lpwfxFormat=format;
  142.   dsbd.dwSize=sizeof(DSBUFFERDESC);
  143.   dsbd.dwBufferBytes=((format->nAvgBytesPerSec/4)+2047)&~2047;
  144.   dsbd.dwFlags=0;
  145.   if(lpDS->CreateSoundBuffer(&dsbd, & s->lpDSB, 0)!=DS_OK)
  146.    return;
  147.   s->NoCallbacks=1;
  148.   s->Playing=1;
  149.   timeBeginPeriod(62);
  150.   if(timeSetEvent(62, 0, StreamTimer, (DWORD)s, TIME_PERIODIC)==0)
  151.   {
  152.    timeEndPeriod(62);
  153.    s->lpDSB->Release();
  154.   }
  155.   else
  156.   {
  157.    s->HalfBufferPoint=dsbd.dwBufferBytes/2;
  158.    s->CurrentPosition=(char*)addr;
  159.    s->BytesLeft=len;
  160.    s->SilenceByte=(format->wBitsPerSample==16)?0:128;
  161.    StreamFillAHalf(s, 0);
  162.    StreamFillAHalf(s, s->HalfBufferPoint);
  163.    s->CloseOnNext=0;
  164.    s->lpDSB->Play(0,0,DSBPLAY_LOOPING);
  165.    s->NoCallbacks=0;
  166.   }
  167.  }
  168. }
  169. }
  170. volatile DSSTREAM Streams[MaxStreams];
  171. void * SoundData[MaxSounds];
  172. WAVEFORMATEX SoundHeader[MaxSounds+1];
  173. int FreeSound=0;
  174. DWORD SoundSize[MaxSounds+1];
  175. bool InitSound(HWND hwnd)
  176. {
  177. int i;
  178. if(DirectSoundCreate(NULL, & lpDS, NULL)!=DS_OK)
  179. {
  180.  IsAvailable=false;
  181.   {
  182.    //fprintf(debugf,"Direct Sound Initialization failed.\n" );
  183.    return false;
  184.   }
  185. }
  186. lpDS->SetCooperativeLevel(hwnd,DSSCL_NORMAL);
  187. //fprintf(debugf,"Direct Sound Initialized.\n" );
  188. for (i=0;i<MaxStreams;i++)
  189.  Streams[i].Playing=0;
  190. IsAvailable=true;
  191.  return true;
  192. }
  193. int LoadWav(char * name)
  194. {
  195. if(!IsAvailable){return -1;}
  196. if (FreeSound>=MaxSounds)
  197. {
  198.  return -1;
  199. }
  200. FILE * fh=fopen(name, "rb" );
  201. if (fh==NULL)
  202. {
  203.  return -1;
  204. }
  205. fseek(fh, 12, 0);
  206. unsigned long tag,size;
  207. short ChannelCount=0,BitsPerSample=0;
  208. long SampleRate=0,SampleSize=0;
  209. char unsigned * psample;
  210. while(!feof(fh))
  211. {
  212.  tag=0;
  213.  if (fread((char *)&tag,4,1,fh)==0)
  214.   break;
  215.  fread((char*)&size,4,1,fh);
  216.  if (tag==0x20746d66)
  217.  {
  218.   fseek(fh,2,SEEK_CUR);
  219.   fread((char*)&ChannelCount,2,1,fh);
  220.   fread((char*)&SampleRate,4,1,fh);
  221.   fseek(fh,6,SEEK_CUR);
  222.   fread((char*)&BitsPerSample,2,1,fh);
  223.   if (size>16)
  224.    fseek(fh,size-16,SEEK_CUR);
  225.  }
  226.  else if (tag==0x61746164)
  227.  {
  228.   psample=(char unsigned*)malloc(size);
  229.   if(psample)
  230.   {
  231.    SampleSize=size;
  232.    fread((char*)psample,size,1,fh);
  233.   }
  234.  }
  235.  else
  236.  {
  237.   fseek(fh,size,SEEK_CUR);
  238.  }
  239. }
  240. fclose(fh);
  241. SoundData[FreeSound]=psample;
  242. SoundSize[FreeSound]=size;
  243. SoundHeader[FreeSound].wFormatTag=WAVE_FORMAT_PCM;
  244. SoundHeader[FreeSound].nChannels=ChannelCount;
  245. SoundHeader[FreeSound].nSamplesPerSec=SampleRate;
  246. SoundHeader[FreeSound].wBitsPerSample=BitsPerSample;
  247. SoundHeader[FreeSound].cbSize=0;
  248. SoundHeader[FreeSound].nBlockAlign=SoundHeader[FreeSound].nChannels*(SoundHeader[FreeSound].wBitsPerSample/8);
  249. SoundHeader[FreeSound].nAvgBytesPerSec=SoundHeader[FreeSound].nBlockAlign*SoundHeader[FreeSound].nSamplesPerSec;
  250. FreeSound++;
  251. return FreeSound-1;
  252. }
  253. void PlayWav(int nsnd)
  254. {
  255. if(!IsAvailable){return;}
  256. if (nsnd==-1)
  257.  return;
  258. int i;
  259. for (i=0; i<MaxStreams; i++)
  260.  if (!Streams[i].Playing)
  261.   break;
  262. if (i < MaxStreams)
  263.  StartStreaming((DSSTREAM *)(Streams+i), SoundData[nsnd], SoundSize[nsnd], lpDS, SoundHeader+nsnd);
  264. else
  265. // fprintf(debugf,"Error playing sound handle %d :Not Enough Channels\n",nsnd);
  266. }
  267. void CloseSound()
  268. {
  269. if(!IsAvailable){return;}
  270. IsAvailable=false;
  271. int i;
  272. for (i=0; i<MaxStreams; i++)
  273.  if (Streams[i].Playing)
  274.   Streams[i].PleaseClose=1;
  275. for (i=0; i<MaxStreams; i++)
  276.  while(Streams[i].Playing){}
  277. for (i=0; i<FreeSound; i++)
  278.  if (SoundData[i]!=NULL)
  279.  free(SoundData[i]);
  280. lpDS->Release();
  281. //fprintf(debugf,"Direct Sound Released.\n" );
  282. }

Reply

Marsh Posté le 13-11-2001 à 07:53:13    

gooopil a écrit a écrit :

J'aimerais savoir comment on fait pour jouer un fichier wav. J'ai regardé whotsit.org, g trouvé ce que cherchais mais je comprend pas énormément de trucs vu que c'est assez énorme. En plus y'a juste le format et pas le code en c++ pour le lire... Ouais faut pas rêver...
Mais j'aimerais bien pouvoir faire ça et vu que c'est pas une priorité, j'aimerais bien ne pas avoir à me casser le cerveau en 2...
Merci  




 
Je ne te parlerai pas de directSound parce que je ne connais pas.
Par contre, pour te renseigner sur les fonctions basiques pour jouer de la musique, regarde les suivantes:
 
- lecture des entêtes de fichier wav: mmioOpen, mmioRead, etc...
mais si tu veux lire toi même l'entête, tu peux aussi le faire (moi c'est ce que je fais souvent).
 
- pour le record:
waveInOpen, waveInUnprepareHeader, waveInPrepareHeader? waveInAddBuffer
 
- pour le play:
waveOutOpen, waveOutUnprepareHeader, waveOutPrepareHeader, waveOutWrite.
 
Ce sont les fonctions principales. En cherchant tout cela dans le MSDN, tu devrais t'en sortir assez rapidement.
 
bon courage. Mais moi je m'étais bien marré à faire ça :D

Reply

Marsh Posté le 13-11-2001 à 08:08:43    

waou gooopil ton topic marche mieux que le mien !

Reply

Marsh Posté le 13-11-2001 à 12:00:54    

sans se casser doit avoir un truc genre PlaySound qui te lit un vaw
 
si c juste pour faire pouet pouet de tps a autre c OK, mais si tu veux quelque chose de plus evoluer (genre tu fais un jeu), faudra te tourner vers directSound
 
le code pour lire le .wav je l'ai, mais pas la, si ca t'interesse fodra attendre un ptit peu (ce soir)

Reply

Marsh Posté le 13-11-2001 à 15:55:45    

ca NOUS interresse (je programme avec gooopil) donc envoie ca dès que tu peut :jap:

Reply

Marsh Posté le 13-11-2001 à 16:19:15    

woue OK, enfin il fait rien de plus que de lire un wav alacon non-compresse, hein ?

Reply

Marsh Posté le 14-11-2001 à 00:14:58    

chrisbk a écrit a écrit :

woue OK, enfin il fait rien de plus que de lire un wav alacon non-compresse, hein ?  




 
C'est ça, je veux juste jouer un wav à la con, c'est juste pour faire plus abouti dans notre projet. Merci tgrx pour ton source

Reply

Marsh Posté le 14-11-2001 à 08:27:05    

youps sorry ca m'est sorti de la tete  
 
je la retente ce soir

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed