tgrx My heart is pumping for love | Adapté depuis des routines de gdmag :
PlayWav.h
Code :
- // PlayWav.h
- // Utilisation :
- // CloseSound()
- // InitSound(hwnd)
- // int wavnum= LoadWav("c:\son.wav" )
- // ...
- // et dans ta boucle principale : PlayWav(wavnum)
- #include <Win32Headers++.pch++>
- #include <windows.h>
- bool InitSound(HWND hwnd);
- int LoadWav(char * name);
- void PlayWav(int nsnd);
- void CloseSound();
|
PlayWav.cpp
Code :
- // PlayWav.cpp
- #include <dsound.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- #include "PlayWav.h"
- LPDIRECTSOUND lpDS;
- const int MaxStreams=32; // voies disponibles
- const int MaxSounds=512; // sons charges en memoire
- static bool IsAvailable=false;
- HRESULT CreatDSBuffer(LPDIRECTSOUND lpDS, LPDIRECTSOUNDBUFFER * lplpDSB, DWORD SoundBytes,
- DWORD frequence, int isStereo, int is16bit);
- HRESULT CreatDSBuffer(LPDIRECTSOUND lpDS, LPDIRECTSOUNDBUFFER * lplpDSB, DWORD SoundBytes,
- DWORD frequence, int isStereo, int is16bit)
- {
- DSBUFFERDESC dsbd;
- PCMWAVEFORMAT fmt;
- fmt.wf.nChannels=(isStereo)?2:1;
- fmt.wBitsPerSample=(is16bit)?16:8;
- fmt.wf.nSamplesPerSec=frequence;
- fmt.wf.nBlockAlign=fmt.wf.nChannels*(fmt.wBitsPerSample>>3);
- fmt.wf.nAvgBytesPerSec=fmt.wf.nSamplesPerSec*fmt.wf.nBlockAlign;
- fmt.wf.wFormatTag=WAVE_FORMAT_PCM;
- memset(&dsbd, 0, sizeof(dsbd));
- dsbd.lpwfxFormat=(LPWAVEFORMATEX)&fmt;
- dsbd.dwSize=sizeof(DSBUFFERDESC);
- dsbd.dwBufferBytes=SoundBytes;
- dsbd.dwFlags=0;
- return (lpDS->CreateSoundBuffer(&dsbd, lplpDSB, 0));
- }
- HRESULT LoadSoundData(LPDIRECTSOUNDBUFFER lpDSB, char * SoundDataPtr, DWORD TotalBytes);
- HRESULT LoadSoundData(LPDIRECTSOUNDBUFFER lpDSB, char * SoundDataPtr, DWORD TotalBytes)
- {
- LPVOID ptr1,ptr2;
- DWORD len1,len2;
- HRESULT result;
- TryLockAgainLabel:
- result=lpDSB->Lock(0,TotalBytes, &ptr1, &len1, &ptr2, & len2, 0);
- switch(result)
- {
- case DS_OK:
- memcpy(ptr1, SoundDataPtr, len1);
- if(ptr2)
- memcpy(ptr2, SoundDataPtr+len1, len2);
- lpDSB->Unlock(ptr1, len1, ptr2, len2);
- break;
- case DSERR_BUFFERLOST:
- result=lpDSB->Restore();
- if (result==DS_OK)
- goto TryLockAgainLabel ;
- break;
- }
- return result;
- }
- typedef struct DSSTREAMTAG
- {
- int Playing, PleaseClose;
- char * CurrentPosition;
- DWORD BytesLeft, NoCallbacks, HalfBufferPoint, LastHalf;
- int CloseOnNext;
- LPDIRECTSOUNDBUFFER lpDSB;
- char SilenceByte;
- } DSSTREAM;
- static void StreamCopy(DSSTREAM * s, char * ptr, DWORD len)
- {
- DWORD amt;
- amt=(len>s->BytesLeft)?s->BytesLeft:len;
- if (amt)
- {
- memcpy(ptr,s->CurrentPosition, amt);
- s->CurrentPosition+=amt;
- s->BytesLeft-=amt;
- }
- len-=amt;
- if(len)
- {
- memset(ptr+amt, s->SilenceByte, len);
- s->CloseOnNext=1;
- }
- }
- static void StreamFillAHalf(DSSTREAM * s, DWORD Half)
- {
- char* ptr1, *ptr2;
- DWORD len1,len2;
- TryLockAgainLabel:
- switch(s->lpDSB->Lock(Half,s->HalfBufferPoint, &ptr1, &len1, &ptr2, & len2, 0))
- {
- case DS_OK:
- StreamCopy(s, ptr1, len1);
- if(ptr2)
- StreamCopy(s, ptr2, len2);
- s->lpDSB->Unlock(ptr1, len1, ptr2, len2);
- break;
- case DSERR_BUFFERLOST:
- if (s->lpDSB->Restore()==DS_OK)
- goto TryLockAgainLabel ;
- break;
- }
- }
- static void CALLBACK StreamTimer(UINT id, UINT msg, DWORD user, DWORD dw1, DWORD dw2)
- {
- DWORD playp, writep;
- DWORD WhichHalf;
- DSSTREAM * s=(DSSTREAM*)user;
- if(s->NoCallbacks++==0)
- {
- if(s->PleaseClose)
- {
- ShutDownStreamingLabel:
- timeKillEvent(id);
- timeEndPeriod(62);
- s->lpDSB->Stop();
- s->lpDSB->Release();
- s->Playing=0;
- return;
- }
- s->lpDSB->GetCurrentPosition(& playp, &writep);
- WhichHalf=(playp<s->HalfBufferPoint)?0:s->HalfBu
- fferPoint;
- if(WhichHalf!=s->LastHalf)
- {
- if(s->CloseOnNext)
- goto ShutDownStreamingLabel;
- StreamFillAHalf(s, s->LastHalf);
- s->LastHalf= WhichHalf;
- }
- }
- s->NoCallbacks--;
- }
- void StartStreaming(DSSTREAM * s, void * addr, DWORD len, LPDIRECTSOUND lpDS, LPWAVEFORMATEX format);
- void StartStreaming(DSSTREAM * s, void * addr, DWORD len, LPDIRECTSOUND lpDS, LPWAVEFORMATEX format)
- {
- DSBUFFERDESC dsbd;
- if (s)
- {
- memset(s, 0, sizeof(DSSTREAM));
- if((addr)&&(lpDS)&&(format))
- {
- memset(&dsbd, 0, sizeof(dsbd));
- dsbd.lpwfxFormat=format;
- dsbd.dwSize=sizeof(DSBUFFERDESC);
- dsbd.dwBufferBytes=((format->nAvgBytesPerSec/4)+2047)&~2047;
- dsbd.dwFlags=0;
- if(lpDS->CreateSoundBuffer(&dsbd, & s->lpDSB, 0)!=DS_OK)
- return;
- s->NoCallbacks=1;
- s->Playing=1;
- timeBeginPeriod(62);
- if(timeSetEvent(62, 0, StreamTimer, (DWORD)s, TIME_PERIODIC)==0)
- {
- timeEndPeriod(62);
- s->lpDSB->Release();
- }
- else
- {
- s->HalfBufferPoint=dsbd.dwBufferBytes/2;
- s->CurrentPosition=(char*)addr;
- s->BytesLeft=len;
- s->SilenceByte=(format->wBitsPerSample==16)?0:128;
- StreamFillAHalf(s, 0);
- StreamFillAHalf(s, s->HalfBufferPoint);
- s->CloseOnNext=0;
- s->lpDSB->Play(0,0,DSBPLAY_LOOPING);
- s->NoCallbacks=0;
- }
- }
- }
- }
- volatile DSSTREAM Streams[MaxStreams];
- void * SoundData[MaxSounds];
- WAVEFORMATEX SoundHeader[MaxSounds+1];
- int FreeSound=0;
- DWORD SoundSize[MaxSounds+1];
- bool InitSound(HWND hwnd)
- {
- int i;
- if(DirectSoundCreate(NULL, & lpDS, NULL)!=DS_OK)
- {
- IsAvailable=false;
- {
- //fprintf(debugf,"Direct Sound Initialization failed.\n" );
- return false;
- }
- }
- lpDS->SetCooperativeLevel(hwnd,DSSCL_NORMAL);
- //fprintf(debugf,"Direct Sound Initialized.\n" );
- for (i=0;i<MaxStreams;i++)
- Streams[i].Playing=0;
- IsAvailable=true;
- return true;
- }
- int LoadWav(char * name)
- {
- if(!IsAvailable){return -1;}
- if (FreeSound>=MaxSounds)
- {
- return -1;
- }
- FILE * fh=fopen(name, "rb" );
- if (fh==NULL)
- {
- return -1;
- }
- fseek(fh, 12, 0);
- unsigned long tag,size;
- short ChannelCount=0,BitsPerSample=0;
- long SampleRate=0,SampleSize=0;
- char unsigned * psample;
- while(!feof(fh))
- {
- tag=0;
- if (fread((char *)&tag,4,1,fh)==0)
- break;
- fread((char*)&size,4,1,fh);
- if (tag==0x20746d66)
- {
- fseek(fh,2,SEEK_CUR);
- fread((char*)&ChannelCount,2,1,fh);
- fread((char*)&SampleRate,4,1,fh);
- fseek(fh,6,SEEK_CUR);
- fread((char*)&BitsPerSample,2,1,fh);
- if (size>16)
- fseek(fh,size-16,SEEK_CUR);
- }
- else if (tag==0x61746164)
- {
- psample=(char unsigned*)malloc(size);
- if(psample)
- {
- SampleSize=size;
- fread((char*)psample,size,1,fh);
- }
- }
- else
- {
- fseek(fh,size,SEEK_CUR);
- }
- }
- fclose(fh);
- SoundData[FreeSound]=psample;
- SoundSize[FreeSound]=size;
- SoundHeader[FreeSound].wFormatTag=WAVE_FORMAT_PCM;
- SoundHeader[FreeSound].nChannels=ChannelCount;
- SoundHeader[FreeSound].nSamplesPerSec=SampleRate;
- SoundHeader[FreeSound].wBitsPerSample=BitsPerSample;
- SoundHeader[FreeSound].cbSize=0;
- SoundHeader[FreeSound].nBlockAlign=SoundHeader[FreeSound].nChannels*(SoundHeader[FreeSound].wBitsPerSample/8);
- SoundHeader[FreeSound].nAvgBytesPerSec=SoundHeader[FreeSound].nBlockAlign*SoundHeader[FreeSound].nSamplesPerSec;
- FreeSound++;
- return FreeSound-1;
- }
- void PlayWav(int nsnd)
- {
- if(!IsAvailable){return;}
- if (nsnd==-1)
- return;
- int i;
- for (i=0; i<MaxStreams; i++)
- if (!Streams[i].Playing)
- break;
- if (i < MaxStreams)
- StartStreaming((DSSTREAM *)(Streams+i), SoundData[nsnd], SoundSize[nsnd], lpDS, SoundHeader+nsnd);
- else
- // fprintf(debugf,"Error playing sound handle %d :Not Enough Channels\n",nsnd);
- }
- void CloseSound()
- {
- if(!IsAvailable){return;}
- IsAvailable=false;
- int i;
- for (i=0; i<MaxStreams; i++)
- if (Streams[i].Playing)
- Streams[i].PleaseClose=1;
- for (i=0; i<MaxStreams; i++)
- while(Streams[i].Playing){}
- for (i=0; i<FreeSound; i++)
- if (SoundData[i]!=NULL)
- free(SoundData[i]);
- lpDS->Release();
- //fprintf(debugf,"Direct Sound Released.\n" );
- }
|
|