3
#include <mme/mme_api.h>
4
#include "mmc_buffers.h"
5
#include "mmc_cmdlin.h"
6
#include "mmc_memory.h"
7
#include "mmc_wave_format.h"
8
#include "mmc_wave_file.h"
13
#define DEFAULT_NCHANNELS 1
14
#define DEFAULT_ENCODING WAVE_FORMAT_MULAW
15
#define DEFAULT_SAMPLESIZE 8
16
#define DEFAULT_SAMPLERATE 8000
18
#define DIV_ROUND_UP_(n,d) ((n + d - 1) / d)
19
#define ROUND_UP_(n,d) (DIV_ROUND_UP_(n,d) * d)
30
struct mmov_soundformat
33
char extra_data[ NUM_DATA ];
37
static mmcWaveFileState_t wavefilestatus = mmcWaveFileStateInitialValue;
38
static mmcBufferList_t mmov_buffer = mmcBufferListInitialValue;
39
static enum mmov_state play_state;
41
static void mmov_cleanup( )
45
mmcBuffersFree (&mmov_buffer);
49
mmcWaveInFileClose (&wavefilestatus);
54
static void mmov_driver (HANDLE hWaveOut,
63
play_state = MMOV_PLAY;
66
play_state = MMOV_CLOSE;
71
int buffer_index = mmcWaveOutGotData (&mmov_buffer, lParam1);
72
mmcBuffer_p bp = &mmov_buffer.b[buffer_index];
73
mmcBufferSetStatus (&mmov_buffer, buffer_index, Empty,
78
mmcVerboseDisplay(Verbose, "Unknown index %d", wMsg);
83
void play_sound_mmov( char* FileName , int verbose )
90
static int uDeviceId = WAVE_MAPPER;
91
static int AdpcmBitsPerSample = 16;
92
static int AdpcmSamplesPerBlock = 0;
93
static int sizeBuffers = 0;
94
static int msBuffers = 0;
95
static int numBuffers = 4;
96
static struct mmov_soundformat sound_format =
107
0, 0, 0, 0, 0, 0, 0, 0,
108
0, 0, 0, 0, 0, 0, 0, 0,
109
0, 0, 0, 0, 0, 0, 0, 0,
110
0, 0, 0, 0, 0, 0, 0, 0
115
play_state = MMOV_START;
117
/* Open the Wave In file */
118
if (mmcWaveInFileOpen (FileName, &sound_format.wave, &wavefilestatus) != 0)
120
mmcVerboseDisplay(Verbose,"Error opening input file");
125
if ( sound_format.wave.wFormatTag == WAVE_FORMAT_PCM)
126
mmcVerboseDisplay(Verbose,"PCM file");
127
else if ( sound_format.wave.wFormatTag == WAVE_FORMAT_MULAW)
128
mmcVerboseDisplay(Verbose,"mu-law file");
129
else if ( sound_format.wave.wFormatTag == WAVE_FORMAT_IMA_ADPCM)
130
mmcVerboseDisplay(Verbose,"IMA file");
132
mmcVerboseDisplay(Verbose,"Unknown sound format %d",
133
sound_format.wave.wFormatTag);
134
mmcVerboseDisplay(Verbose,"Channels = %d ", sound_format.wave.nChannels );
135
mmcVerboseDisplay(Verbose,"Sample rate = %d",
136
sound_format.wave.nSamplesPerSec);
137
mmcVerboseDisplay(Verbose,
138
"Sample size = %d", sound_format.wave.wBitsPerSample );
140
if( sound_format.wave.nChannels == 0)
141
sound_format.wave.nChannels = DEFAULT_NCHANNELS;
142
if( sound_format.wave.nSamplesPerSec == 0)
143
sound_format.wave.nSamplesPerSec = DEFAULT_SAMPLERATE;
144
if( sound_format.wave.wBitsPerSample == 0)
145
sound_format.wave.wBitsPerSample = DEFAULT_SAMPLESIZE;
147
if ( sound_format.wave.wFormatTag == WAVE_FORMAT_IMA_ADPCM ) {
148
AdpcmSamplesPerBlock = *(Uint16 *)(&sound_format.extra_data[0]);
151
if ( ( sound_format.wave.wFormatTag == WAVE_FORMAT_PCM) ||
152
( sound_format.wave.wFormatTag == WAVE_FORMAT_MULAW) ) {
153
mask1 = WAVE_FORMAT_FIX_BLOCK_ALIGN | WAVE_FORMAT_FIX_AVG_BPS;
154
mmcWaveFormatFix((LPPCMWAVEFORMAT)(&sound_format), mask1 );
157
if ( sound_format.wave.wFormatTag == WAVE_FORMAT_IMA_ADPCM) {
158
sizeBuffers = sound_format.wave.nBlockAlign;
159
msBuffers = sizeBuffers * 1000 /
160
(DIV_ROUND_UP_(AdpcmBitsPerSample,8) *
161
sound_format.wave.nSamplesPerSec *
162
sound_format.wave.nChannels);
166
if (!msBuffers && !sizeBuffers)
167
msBuffers = 1000/numBuffers;
171
ROUND_UP_(DIV_ROUND_UP_(msBuffers *
172
DIV_ROUND_UP_( sound_format.wave.wBitsPerSample,
174
sound_format.wave.nSamplesPerSec *
175
sound_format.wave.nChannels,1000), BUFFER_PAD);
178
sizeBuffers = ROUND_UP_(sizeBuffers, BUFFER_PAD);
179
msBuffers = sizeBuffers * 1000 /
180
(DIV_ROUND_UP_( sound_format.wave.wBitsPerSample,8) *
181
sound_format.wave.nSamplesPerSec *
182
sound_format.wave.nChannels);
187
mmcVerboseDisplay(Verbose, "Buffer size = %d bytes or %d milliseconds",
188
sizeBuffers, msBuffers);
192
status = mmcWaveOutOpen(&sound_format.wave, uDeviceId, &mmov_driver ,
193
WAVE_OPEN_SHAREABLE, &hwaveout);
195
if (status != MMSYSERR_NOERROR)
201
if (mmcBuffersCreate (&mmov_buffer, numBuffers, sizeBuffers, BUFFER_PAD)
210
switch ( play_state )
216
status = mmcWaveOutQueueBufferAll (hwaveout, &mmov_buffer, Verbose,
217
&wavefilestatus, &allDone);
219
play_state = MMOV_WAITING;
222
if (status != MMSYSERR_NOERROR)
231
if ((mmcBufferFind(&mmov_buffer,Filling) != mmcBufferNone) ||
232
(mmcBufferFind(&mmov_buffer,Full) != mmcBufferNone) ||
233
(mmcBufferFind(&mmov_buffer,Playing) != mmcBufferNone))
235
play_state = MMOV_CLOSE;
238
status = mmcWaveOutClose (hwaveout, &mmov_buffer);
239
if (status != MMSYSERR_NOERROR)
248
mmcVerboseDisplay(Verbose,"Unknown play_state %d", play_state);
253
mmeWaitForCallbacks (); /* block so we don't hog 100% of the CPU */
254
mmeProcessCallbacks ();