-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSoundServer.cpp
executable file
·129 lines (101 loc) · 3.67 KB
/
SoundServer.cpp
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
/*********************************************************************************
SoundServer - Written by Arnaud Carré (aka Leonard / OXYGENE)
Part of the "Leonard Homepage Articles".
http://leonard.oxg.free.fr
Read the complete article on my web page:
PART 1: Using WaveOut API.
How to make a SoundServer under windows, to play various sound.
WARNING: This sample plays a 44.1Khz, 16bits, mono sound. Should be quite easy to modify ! :-)
WARNING: You have to link this with the Windows MultiMedia library. (WINMM.LIB)
*********************************************************************************/
#include <windows.h>
#include "SoundServer.h"
#pragma comment(lib,"winmm.lib")
// Internal WaveOut API callback function. We just call our sound handler ("playNextBuffer")
static void CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
if (WOM_DONE == uMsg)
{
CSoundServer *pServer = (CSoundServer*)dwInstance;
if (pServer)
{
if (pServer->IsRunning())
pServer->fillNextBuffer();
}
}
}
CSoundServer::CSoundServer()
{
m_pUserCallback = NULL;
m_currentBuffer = 0;
}
CSoundServer::~CSoundServer()
{
close();
}
BOOL CSoundServer::open(USER_CALLBACK pUserCallback,long totalBufferedSoundLen)
{
m_pUserCallback = pUserCallback;
m_bufferSize = ((totalBufferedSoundLen * REPLAY_RATE) / 1000) * REPLAY_SAMPLELEN;
m_bufferSize /= REPLAY_NBSOUNDBUFFER;
WAVEFORMATEX wfx;
wfx.wFormatTag = 1; // PCM standart.
wfx.nChannels = 1; // Mono
wfx.nSamplesPerSec = REPLAY_RATE;
wfx.nAvgBytesPerSec = REPLAY_RATE*REPLAY_SAMPLELEN;
wfx.nBlockAlign = REPLAY_SAMPLELEN;
wfx.wBitsPerSample = REPLAY_DEPTH;
wfx.cbSize = 0;
MMRESULT errCode = waveOutOpen( &m_hWaveOut,
WAVE_MAPPER,
&wfx,
(DWORD)waveOutProc,
(DWORD)this, // User data.
(DWORD)CALLBACK_FUNCTION);
if (errCode != MMSYSERR_NOERROR) return FALSE;
// Alloc the sample buffers.
for (int i=0;i<REPLAY_NBSOUNDBUFFER;i++)
{
m_pSoundBuffer[i] = malloc(m_bufferSize);
memset(&m_waveHeader[i],0,sizeof(WAVEHDR));
memset(m_pSoundBuffer[i],0,m_bufferSize);
}
// Fill all the sound buffers
m_currentBuffer = 0;
for (int i=0;i<REPLAY_NBSOUNDBUFFER;i++)
fillNextBuffer();
return TRUE;
}
void CSoundServer::close(void)
{
if (IsRunning())
{
m_pUserCallback = NULL;
waveOutReset(m_hWaveOut); // Reset tout.
for (int i=0;i<REPLAY_NBSOUNDBUFFER;i++)
{
if (m_waveHeader[i].dwFlags & WHDR_PREPARED)
waveOutUnprepareHeader(m_hWaveOut,&m_waveHeader[i],sizeof(WAVEHDR));
free(m_pSoundBuffer[i]);
}
waveOutClose(m_hWaveOut);
}
}
void CSoundServer::fillNextBuffer(void)
{
// check if the buffer is already prepared (should not !)
if (m_waveHeader[m_currentBuffer].dwFlags&WHDR_PREPARED)
waveOutUnprepareHeader(m_hWaveOut,&m_waveHeader[m_currentBuffer],sizeof(WAVEHDR));
// Call the user function to fill the buffer with anything you want ! :-)
if (m_pUserCallback)
m_pUserCallback(m_pSoundBuffer[m_currentBuffer],m_bufferSize);
// Prepare the buffer to be sent to the WaveOut API
m_waveHeader[m_currentBuffer].lpData = (char*)m_pSoundBuffer[m_currentBuffer];
m_waveHeader[m_currentBuffer].dwBufferLength = m_bufferSize;
waveOutPrepareHeader(m_hWaveOut,&m_waveHeader[m_currentBuffer],sizeof(WAVEHDR));
// Send the buffer the the WaveOut queue
waveOutWrite(m_hWaveOut,&m_waveHeader[m_currentBuffer],sizeof(WAVEHDR));
m_currentBuffer++;
if (m_currentBuffer >= REPLAY_NBSOUNDBUFFER) m_currentBuffer = 0;
}