123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- #include <windows.h>
- #include <math.h>
- #define _AUDIO_
- #include "audio.h"
- HANDLE hAudioThread;
- DWORD AudioTId;
- WAVEFORMATEX wf;
- HWND hwndApp;
- BOOL AudioNeedRestore;
- char logtt[128];
- void PrintLog(LPSTR l);
- int InitDirectSound( HWND );
- BOOL CALLBACK EnumerateSoundDevice(GUID FAR *, LPSTR, LPSTR, LPVOID );
- void Audio_MixSound(int DestAddr, int SrcAddr, int MixLen, int LVolume, int RVolume);
- void Audio_MixChannels();
- void Audio_MixAmbient();
- void Audio_MixAmbient3d();
- DWORD WINAPI ProcessAudioThread (LPVOID ptr)
- {
- for (;;) {
- if (iSoundActive)
- ProcessAudio();
- Sleep(70);
- }
- return 0;
- }
- void Init_SetCooperative()
- {
-
- }
- int InitDirectSound( HWND hwnd)
- {
- PrintLog("\n");
- PrintLog("==Init Direct Sound==\n");
-
- HRESULT hres;
- iTotalSoundDevices = 0;
- lpSoundBuffer = (char*) _SoundBufferData;
- if( !lpSoundBuffer )
- return 0;
- PrintLog("Back Sound Buffer created.\n");
- for( int i = 0; i < MAX_SOUND_DEVICE; i++ )
- sdd[i].DSC.dwSize = sizeof( DSCAPS );
-
- hres = DirectSoundEnumerate( (LPDSENUMCALLBACK)EnumerateSoundDevice, NULL);
- if( hres != DS_OK ) {
- wsprintf(logtt, "DirectSoundEnumerate Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("DirectSoundEnumerate: Ok\n");
- iTotal16SD = 0;
- for( i = 0; i < iTotalSoundDevices; i++ ) {
- LPDIRECTSOUND lpds;
- if( DirectSoundCreate( &sdd[i].Guid, &lpds, NULL ) != DS_OK ) continue;
- if( lpds->GetCaps( &sdd[i].DSC ) != DS_OK ) continue;
- if( sdd[i].DSC.dwFlags & (DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO | DSCAPS_SECONDARY16BIT | DSCAPS_SECONDARYSTEREO ) ) {
- sdd[i].status = 1;
- iTotal16SD++;
- wsprintf(logtt,"Acceptable device: %d\n",i);
- PrintLog(logtt);
- }
- }
- if (!iTotal16SD) return 0;
- iCurrentDriver = 0;
- while( !sdd[iCurrentDriver].status )
- iCurrentDriver++;
-
- wsprintf(logtt,"Device selected : %d\n",iCurrentDriver);
- PrintLog(logtt);
- hres = DirectSoundCreate( &sdd[iCurrentDriver].Guid, &lpDS, NULL );
- if( (hres != DS_OK) || (!lpDS) ) {
- wsprintf(logtt, "DirectSoundCreate Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("DirectSoundCreate: Ok\n");
- PrimaryMode = TRUE;
- PrintLog("Attempting to set WRITEPRIMARY CooperativeLevel:\n");
- hres = lpDS->SetCooperativeLevel( hwnd, DSSCL_WRITEPRIMARY );
- if (hres != DS_OK) {
- wsprintf(logtt, "SetCooperativeLevel Error: %Xh\n", hres);
- PrintLog(logtt);
- PrimaryMode = FALSE;
- } else
- PrintLog("Set Cooperative : Ok\n");
- if (!PrimaryMode) {
- PrintLog("Attempting to set EXCLUSIVE CooperativeLevel:\n");
- hres = lpDS->SetCooperativeLevel( hwnd, DSSCL_EXCLUSIVE);
- if (hres != DS_OK) {
- wsprintf(logtt, "==>>SetCooperativeLevel Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("Set Cooperative : Ok\n");
- }
- /*======= creating primary buffer ==============*/
- CopyMemory( &WaveFormat, &wf, sizeof( WAVEFORMATEX ) );
-
- DSBUFFERDESC dsbd;
- dsbd.dwSize = sizeof( DSBUFFERDESC );
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
- dsbd.dwBufferBytes = 0;
- dsbd.lpwfxFormat = NULL;
- dsbd.dwReserved = 0;
-
- hres = lpDS->CreateSoundBuffer( &dsbd, &lpdsPrimary, NULL );
- if( hres != DS_OK ) {
- wsprintf(logtt, "==>>CreatePrimarySoundBuffer Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("CreateSoundBuffer: Ok (Primary)\n");
- lpdsWork = lpdsPrimary;
- hres = lpdsPrimary->SetFormat( &wf );
- if( hres != DS_OK ) {
- wsprintf(logtt, "SetFormat Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("SetFormat : Ok\n");
-
- if (PrimaryMode) goto SKIPSECONDARY;
- // ========= creating secondary ================//
- dsbd.dwSize = sizeof( DSBUFFERDESC );
- dsbd.dwFlags = 0;
- dsbd.dwBufferBytes = 2*8192;
- dsbd.lpwfxFormat = &wf;
- dsbd.dwReserved = 0;
-
- hres = lpDS->CreateSoundBuffer( &dsbd, &lpdsSecondary, NULL );
- if( hres != DS_OK ) {
- wsprintf(logtt, "CreateSecondarySoundBuffer Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("CreateSoundBuffer: Ok (Secondary)\n");
- lpdsWork = lpdsSecondary;
- SKIPSECONDARY:
-
-
- DSBCAPS dsbc;
- dsbc.dwSize = sizeof( DSBCAPS );
- lpdsWork->GetCaps( &dsbc );
- iBufferLength = dsbc.dwBufferBytes;
- iBufferLength /= 8192;
-
- hres = lpdsWork->Play( 0, 0, DSBPLAY_LOOPING );
- if( hres != DS_OK ) {
- wsprintf(logtt, "Play Error: %Xh\n", hres);
- PrintLog(logtt);
- return 0;
- }
- PrintLog("Play : Ok\n");
-
- iSoundActive = 1;
- FillMemory( channel, sizeof( CHANNEL )*MAX_CHANNEL, 0 );
- ambient.iLength = 0;
- hAudioThread = CreateThread(NULL, 0, ProcessAudioThread, NULL, 0, &AudioTId);
- SetThreadPriority(hAudioThread, THREAD_PRIORITY_HIGHEST);
- PrintLog("Direct Sound activated.\n");
- return 1;
- }
- void InitAudioSystem(HWND hw)
- {
- hwndApp = hw;
- wf.wFormatTag = WAVE_FORMAT_PCM;
- wf.nChannels = 2;
- wf.nSamplesPerSec = 11025*2;
- wf.nAvgBytesPerSec = 44100*2;
- wf.nBlockAlign = 4;
- wf.wBitsPerSample = 16;
- wf.cbSize = 0;
- if( !InitDirectSound( hwndApp ) )
- PrintLog("Sound System failed\n");
- }
- void AudioStop()
- {
- FillMemory(&ambient, sizeof(ambient), 0);
- FillMemory(&mambient, sizeof(mambient), 0);
- FillMemory(&ambient2, sizeof(ambient2), 0);
- FillMemory(channel, sizeof( CHANNEL )*MAX_CHANNEL, 0 );
- AudioNeedRestore = TRUE;
- }
- void AudioSetCameraPos(float cx, float cy, float cz, float ca, float cb)
- {
- xCamera = (int) cx;
- yCamera = (int) cy;
- zCamera = (int) cz;
- alphaCamera = ca;
- cosa = (float)cos(ca);
- sina = (float)sin(ca);
- }
- void SetAmbient(int length, short int* lpdata, int av)
- {
- if (!iSoundActive) return;
-
- if (ambient.lpData == lpdata) return;
-
- ambient2 = ambient;
- ambient.iLength = length;
- ambient.lpData = lpdata;
- ambient.iPosition = 0;
- ambient.volume = 0;
- ambient.avolume = av;
- }
- void SetAmbient3d(int length, short int* lpdata, float cx, float cy, float cz)
- {
- if (!iSoundActive) return;
-
- if (mambient.iPosition >= length) mambient.iPosition = 0;
-
- mambient.iLength = length;
- mambient.lpData = lpdata;
- mambient.x = cx;
- mambient.y = cy;
- mambient.z = cz;
- }
- void AddVoice3dv(int length, short int* lpdata, float cx, float cy, float cz, int vol)
- {
- if (!iSoundActive) return;
- if (lpdata == 0) return;
- for( int i = 0; i < MAX_CHANNEL; i++ )
- if( !channel[i].status ) {
- channel[i].iLength = length;
- channel[i].lpData = lpdata;
- channel[i].iPosition = 0;
- channel[i].x = (int)cx;
- channel[i].y = (int)cy;
- channel[i].z = (int)cz;
- channel[i].status = 1;
- channel[i].volume = vol;
- return;
- }
- return;
- }
- void AddVoice3d(int length, short int* lpdata, float cx, float cy, float cz)
- {
- AddVoice3dv(length, lpdata, cx, cy, cz, 256);
- }
- void AddVoicev(int length, short int* lpdata, int v)
- {
- AddVoice3dv(length, lpdata, 0, 0, 0, v);
- }
- void AddVoice(int length, short int* lpdata)
- {
- AddVoice3dv(length, lpdata, 0,0,0, 256);
- }
- BOOL CALLBACK EnumerateSoundDevice( GUID* lpGuid, LPSTR lpstrDescription, LPSTR lpstrModule, LPVOID lpContext)
- {
- if( lpGuid == NULL )
- if( !iTotalSoundDevices )
- return TRUE;
- else
- return FALSE;
- wsprintf(logtt,"Device%d: ",iTotalSoundDevices);
- PrintLog(logtt);
- PrintLog(lpstrDescription);
- PrintLog("/");
- PrintLog(lpstrModule);
- PrintLog("\n");
-
- CopyMemory( &sdd[iTotalSoundDevices].Guid, lpGuid, sizeof( GUID ) );
- iTotalSoundDevices++;
- return TRUE;
- }
- void Audio_Shutdown()
- {
- if (!iSoundActive) return;
-
- lpdsWork->Stop();
- TerminateThread(hAudioThread ,0);
- }
- void Audio_Restore()
- {
- if (!iSoundActive) return;
-
- lpdsWork->Stop();
- lpdsWork->Restore();
- HRESULT hres = lpdsWork->Play( 0, 0, DSBPLAY_LOOPING );
- if (hres != DS_OK) AudioNeedRestore = TRUE;
- else AudioNeedRestore = FALSE;
-
- if (!AudioNeedRestore)
- PrintLog("Audio restored.\n");
- }
- int ProcessAudio()
- {
- LPVOID lpStart1;
- LPVOID lpStart2;
- DWORD len1, len2;
- HRESULT hres;
- static int PrevBlock = 1;
- if (AudioNeedRestore) Audio_Restore();
- if (AudioNeedRestore) return 1;
- hres = lpdsWork->GetCurrentPosition( &len1, &dwWritePos );
- hres = lpdsWork->GetCurrentPosition( &len2, &dwWritePos );
- if( hres != DS_OK ) { AudioNeedRestore = TRUE; return 0; }
- if ( (len1>len2) || (len1<len2+16) )
- hres = lpdsWork->GetCurrentPosition( &len2, &dwWritePos );
-
- if (len1+len2==0) {
- Sleep(5);
- lpdsWork->GetCurrentPosition( &len2, &dwWritePos );
- if (!len2) { AudioNeedRestore = TRUE; return 0; }
- }
- dwPlayPos = len2;
- int CurBlock = dwPlayPos / (4096*2);
- if (CurBlock==PrevBlock) return 1;
- if( (int)dwPlayPos < CurBlock*4096*2 + 2) return 1; // it's no time to put info
- FillMemory( lpSoundBuffer, MAX_BUFFER_LENGTH*2, 0 );
- Audio_MixChannels();
- Audio_MixAmbient();
- Audio_MixAmbient3d();
- PrevBlock = CurBlock;
- int NextBlock = (CurBlock + 1) % iBufferLength;
- hres = lpdsWork->Lock(NextBlock*4096*2, 4096*2, &lpStart1, &len1, &lpStart2, &len2, 0 );
- if( hres != DS_OK ) {
- return 0;
- }
-
- CopyMemory( lpStart1, lpSoundBuffer, 4096*2);
-
- hres = lpdsWork->Unlock( lpStart1, len1, lpStart2, len2 );
- if( hres != DS_OK )
- return 0;
-
- return 1;
- }
- void CalcLRVolumes(int v0, int x, int y, int z, int &lv, int &rv)
- {
- if (x==0) {
- lv = v0*180;
- rv = v0*180;
- return; }
- v0*=200;
- x-=xCamera;
- y-=yCamera;
- z-=zCamera;
- float xx = (float)x * cosa + (float)z * sina;
- float yy = (float)y;
- float zz = (float)fabs((float)z * cosa - (float)x * sina);
- float xa = (float)fabs(xx);
- float l = 0.8f;
- float r = 0.8f;
- float d = (float)sqrt( xx*xx + yy*yy + zz*zz) - MIN_RADIUS;
- float k;
- if (d<=0) k=1.f;
- //else k = (MAX_RADIUS - d) / MAX_RADIUS;
- else k = 1224.f / (1224 + d);
- if (d>6000) {
- d-=6000;
- k = k * (4000 - d) / (4000);
- }
- if (k<0) k=0.f;
- float fi = (float)atan2(xa, zz);
- r = 0.7f + 0.3f * fi / (3.141593f/2.f);
- l = 0.7f - 0.6f * fi / (3.141593f/2.f);
- if (xx>0) { lv=(int)(v0*l*k); rv=(int)(v0*r*k); }
- else { lv=(int)(v0*r*k); rv=(int)(v0*l*k); }
- }
- void Audio_MixChannels()
- {
- int iMixLen;
- int srcofs;
- int LV, RV;
- for( int i = 0; i < MAX_CHANNEL; i++ )
- if( channel[ i ].status ) {
- if( channel[ i ].iPosition + 2048*2 >= channel[ i ].iLength )
- iMixLen = (channel[ i ].iLength - channel[ i ].iPosition)>>1;
- else
- iMixLen = 1024*2;
- srcofs = (int) channel[i].lpData + channel[i].iPosition;
- CalcLRVolumes(channel[i].volume, channel[i].x, channel[i].y, channel[i].z, LV, RV);
- if (LV || RV)
- Audio_MixSound((int)lpSoundBuffer, srcofs, iMixLen, LV, RV);
- if (channel[ i ].iPosition + 2048*2 >= channel[ i ].iLength )
- channel[ i ].status = 0; else channel[ i ].iPosition += 2048*2;
- }
- }
- void Audio_DoMixAmbient(AMBIENT &ambient)
- {
- if (ambient.lpData==0) return;
- int iMixLen,srcofs;
- int v = (32000 * ambient.volume * ambient.avolume) / 256 / 256;
- if( ambient.iPosition + 2048*2 >= ambient.iLength )
- iMixLen = (ambient.iLength - ambient.iPosition)>>1;
- else iMixLen = 1024*2;
- srcofs = (int) ambient.lpData + ambient.iPosition;
- Audio_MixSound((int)lpSoundBuffer, srcofs, iMixLen, v, v);
- if (ambient.iPosition + 2048*2 >= ambient.iLength )
- ambient.iPosition=0; else ambient.iPosition += 2048*2;
-
- if (iMixLen<1024*2) {
- Audio_MixSound((int)lpSoundBuffer + iMixLen*4,
- (int)ambient.lpData, 1024*2-iMixLen, v, v);
- ambient.iPosition+=(1024*2-iMixLen)*2;
- }
- }
- void Audio_MixAmbient()
- {
- Audio_DoMixAmbient(ambient);
- if (ambient.volume<256) ambient.volume = min(ambient.volume+16, 256);
- if (ambient2.volume) Audio_DoMixAmbient(ambient2);
- if (ambient2.volume>0) ambient2.volume = max(ambient2.volume-16, 0);
- }
- void Audio_MixAmbient3d()
- {
- if (mambient.lpData==0) return;
- int iMixLen,srcofs;
- int LV, RV;
- CalcLRVolumes(256, (int)mambient.x, (int)mambient.y, (int)mambient.z, LV, RV);
- if (!(LV || RV)) return;
- if( mambient.iPosition + 2048*2 >= mambient.iLength )
- iMixLen = (mambient.iLength - mambient.iPosition)>>1;
- else iMixLen = 1024*2;
- srcofs = (int) mambient.lpData + mambient.iPosition;
- Audio_MixSound((int)lpSoundBuffer, srcofs, iMixLen, LV, RV);
- if (mambient.iPosition + 2048*2 >= mambient.iLength )
- mambient.iPosition=0; else mambient.iPosition += 2048*2;
-
- if (iMixLen<1024*2) {
- Audio_MixSound((int)lpSoundBuffer + iMixLen*4,
- (int)mambient.lpData, 1024*2-iMixLen, LV, RV);
- mambient.iPosition+=(1024*2-iMixLen)*2;
- }
- }
- void Audio_MixSound(int DestAddr, int SrcAddr, int MixLen, int LVolume, int RVolume)
- {
- _asm {
- mov edi, DestAddr
- mov ecx, MixLen
- mov esi, SrcAddr
- }
-
- SOUND_CYCLE :
- _asm {
- movsx eax, word ptr [esi]
- imul LVolume
- sar eax, 16
- mov bx, word ptr [edi]
-
- add ax, bx
- jo LEFT_CHECK_OVERFLOW
- mov word ptr [edi], ax
- jmp CYCLE_RIGHT
- }
- LEFT_CHECK_OVERFLOW :
- __asm {
- cmp bx, 0
- js LEFT_MAX_NEGATIVE
- mov ax, 32767
- mov word ptr [edi], ax
- jmp CYCLE_RIGHT
- }
- LEFT_MAX_NEGATIVE :
- __asm mov word ptr [edi], -32767
-
-
- CYCLE_RIGHT :
- __asm {
- movsx eax, word ptr [esi]
- imul dword ptr RVolume
- sar eax, 16
- mov bx, word ptr [edi+2]
-
- add ax, bx
- jo RIGHT_CHECK_OVERFLOW
- mov word ptr [edi+2], ax
- jmp CYCLE_CONTINUE
- }
- RIGHT_CHECK_OVERFLOW :
- __asm {
- cmp bx, 0
- js RIGHT_MAX_NEGATIVE
- mov word ptr [edi+2], 32767
- jmp CYCLE_CONTINUE
- }
- RIGHT_MAX_NEGATIVE :
- __asm mov word ptr [edi+2], -32767
-
- CYCLE_CONTINUE :
- __asm {
- add edi, 4
- add esi, 2
- dec ecx
- jnz SOUND_CYCLE
- }
- }
|