00001 #include <stdio.h>
00002 #include "WavePlayer.h"
00003
00004 TWavePlayerWindow::TWavePlayerWindow(TWavePlayer *Wave) : THiddenWindow("WavePlayerWindow")
00005 {
00006 WavePlayer = Wave;
00007 }
00008
00009 void TWavePlayerWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
00010 {
00011 if (uMsg == WM_APP + 111)
00012 WavePlayer->RecordComplete();
00013 else if (uMsg == WM_APP + 222)
00014 WavePlayer->PlayComplete();
00015 }
00016
00017 static void CALLBACK WavePlayerInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
00018 {
00019 TWavePlayer *WavePlayer;
00020
00021 if (uMsg == WIM_DATA)
00022 {
00023 WavePlayer = (TWavePlayer *)dwInstance;
00024 if (WavePlayer->GetMode() != TWavePlayer::IDLE)
00025 WavePlayer->RecordABuffer();
00026 }
00027 }
00028
00029 static void CALLBACK WavePlayerOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
00030 {
00031 TWavePlayer *WavePlayer;
00032
00033 if (uMsg == WOM_DONE)
00034 {
00035 WavePlayer = (TWavePlayer *)dwInstance;
00036 if (WavePlayer->GetMode() != TWavePlayer::IDLE)
00037 WavePlayer->PlayABuffer();
00038 }
00039 }
00040
00041 TWavePlayer::TWavePlayer(int sampleRate, int bitRate) : Speaker()
00042 {
00043 int i;
00044
00045 mode = IDLE;
00046 echoOn = false;
00047 echoVolume = 5;
00048 wave = NULL;
00049 Clear();
00050
00051 for (i = 0; i < 3; i++)
00052 {
00053 waveInHdr[i].lpData = NULL;
00054 waveOutHdr[i].lpData = NULL;
00055 }
00056
00057 SetFormat(sampleRate, bitRate);
00058 SetBufferSize(sampleRate / 5);
00059 HiddenWindow = new TWavePlayerWindow(this);
00060 }
00061
00062 TWavePlayer::~TWavePlayer()
00063 {
00064 StopRecord();
00065 StopPlay();
00066 Clear();
00067 delete HiddenWindow;
00068 }
00069
00070 int TWavePlayer::GetMode(void)
00071 {
00072 return mode;
00073 }
00074
00075 int TWavePlayer::GetSampleRate(void)
00076 {
00077 return waveFormat.nSamplesPerSec;
00078 }
00079
00080 int TWavePlayer::GetBitRate(void)
00081 {
00082 return waveFormat.wBitsPerSample;
00083 }
00084
00085 bool TWavePlayer::IsEchoOn(void)
00086 {
00087 return echoOn;
00088 }
00089
00090 void TWavePlayer::SetFormat(int newSampleRate, int newBitRate)
00091 {
00092 int i;
00093
00094 if (mode != IDLE)
00095 return;
00096
00097 if (newBitRate != GetBitRate())
00098 {
00099 if (newBitRate == 8)
00100 for (i = 0; i < waveSize; i++)
00101 wave[i] = wave[i] >> 8;
00102 else
00103 for (i = 0; i < waveSize; i++)
00104 wave[i] = wave[i] << 8;
00105 }
00106 Resample(newSampleRate);
00107
00108 waveFormat.wFormatTag = WAVE_FORMAT_PCM;
00109 waveFormat.nChannels = 1;
00110 waveFormat.nSamplesPerSec = newSampleRate;
00111 waveFormat.wBitsPerSample = newBitRate;
00112 waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
00113 waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
00114 waveFormat.cbSize = 0;
00115
00116 bytesPerSample = newBitRate / 8;
00117 bytesPerBuffer = bufferSize * bytesPerSample;
00118 }
00119
00120 void TWavePlayer::Resample(int newSampleRate)
00121 {
00122 int i, j, r, n, sampleRate;
00123 int *newWave;
00124
00125 sampleRate = GetSampleRate();
00126 if (newSampleRate == sampleRate || waveSize == 0)
00127 return;
00128
00129
00130
00131 r = (waveSize - 1) % sampleRate;
00132 waveSize = (waveSize - 1 - r) / sampleRate * newSampleRate + r * newSampleRate / sampleRate;
00133 bufferTotal = (waveSize + bufferSize - 1) / bufferSize;
00134 newWave = new int[bufferTotal * bufferSize + 16000];
00135 for (i = 0; i < waveSize; i++)
00136 {
00137
00138
00139 r = i % newSampleRate;
00140 j = (i - r) / newSampleRate * sampleRate + r * sampleRate / newSampleRate;
00141 n = (10.0f * i * sampleRate) / newSampleRate - 10 * j;
00142 newWave[i] = (wave[j] * (10 - n) + wave[j + 1] * n) / 10;
00143 }
00144 memset(newWave + waveSize, 0, (bufferTotal * bufferSize + 16000 - waveSize) * sizeof(int));
00145
00146 delete[] wave;
00147 wave = newWave;
00148 }
00149
00150 int TWavePlayer::GetBufferSize(void)
00151 {
00152 return bufferSize;
00153 }
00154
00155 void TWavePlayer::SetBufferSize(int size)
00156 {
00157 if (mode != IDLE)
00158 return;
00159
00160 bufferSize = size;
00161 bytesPerBuffer = bufferSize * bytesPerSample;
00162 bufferTotal = (waveSize + bufferSize - 1) / bufferSize;
00163 }
00164
00165 void TWavePlayer::SetWave(int *w, int size)
00166 {
00167 if (mode != IDLE)
00168 return;
00169
00170 Clear();
00171 waveSize = size;
00172 duration = (float)waveSize / GetSampleRate();
00173 bufferTotal = (waveSize + bufferSize - 1) / bufferSize;
00174 wave = new int[bufferTotal * bufferSize + 16000];
00175 memcpy(wave, w, waveSize * sizeof(int));
00176 memset(wave + waveSize, 0, (bufferTotal * bufferSize + 16000 - waveSize) * sizeof(int));
00177 }
00178
00179 void TWavePlayer::SetWave(TWaveFile *WaveFile)
00180 {
00181 if (mode != IDLE)
00182 return;
00183
00184 Clear();
00185 SetFormat(WaveFile->GetSampleRate(), WaveFile->GetBitRate());
00186 SetWave(WaveFile->wave, WaveFile->waveSize);
00187 }
00188
00189 bool TWavePlayer::Load(char *name)
00190 {
00191 TWaveFile WaveFile;
00192
00193 if (mode != IDLE)
00194 return false;
00195
00196 Clear();
00197 if (!WaveFile.Load(name))
00198 return false;
00199 SetWave(&WaveFile);
00200 return true;
00201 }
00202
00203 bool TWavePlayer::Save(char *name)
00204 {
00205 TWaveFile WaveFile;
00206
00207 if (mode != IDLE)
00208 return false;
00209
00210 WaveFile.SetFormat(GetSampleRate(), GetBitRate());
00211 WaveFile.SetWave(wave, waveSize);
00212 return WaveFile.Save(name);
00213 }
00214
00215 bool TWavePlayer::OpenRecordDevice(void)
00216 {
00217 int i;
00218
00219 if (mode == RECORDING)
00220 return true;
00221
00222 if (waveInOpen(&waveIn, WAVE_MAPPER, &waveFormat, (DWORD)WavePlayerInProc, (DWORD)this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
00223 return false;
00224
00225 for (i = 0; i < 3; i++)
00226 {
00227 waveInHdr[i].dwBufferLength = bytesPerBuffer;
00228 waveInHdr[i].lpData = new char[bytesPerBuffer];
00229 waveInHdr[i].dwFlags = 0;
00230 memset(waveInHdr[i].lpData, bytesPerSample == 1? 128 : 0, bytesPerBuffer);
00231 waveInPrepareHeader(waveIn, waveInHdr + i, sizeof(WAVEHDR));
00232 }
00233
00234 waveInAddBuffer(waveIn, waveInHdr, sizeof(WAVEHDR));
00235 waveInAddBuffer(waveIn, waveInHdr + 1, sizeof(WAVEHDR));
00236 return true;
00237 }
00238
00239 void TWavePlayer::CloseRecordDevice(void)
00240 {
00241 int i;
00242
00243 waveInReset(waveIn);
00244 for (i = 0; i < 3; i++)
00245 {
00246 waveInUnprepareHeader(waveIn, waveInHdr + i, sizeof(WAVEHDR));
00247 delete[] waveInHdr[i].lpData;
00248 waveInHdr[i].lpData = NULL;
00249 }
00250 waveInClose(waveIn);
00251 }
00252
00253 bool TWavePlayer::OpenPlayDevice(void)
00254 {
00255 int i;
00256
00257 if (mode == PLAYING)
00258 return true;
00259
00260 if (waveOutOpen(&waveOut, WAVE_MAPPER, &waveFormat, (DWORD)WavePlayerOutProc, (DWORD)this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
00261 return false;
00262
00263 for (i = 0; i < 3; i++)
00264 {
00265 waveOutHdr[i].dwBufferLength = bytesPerBuffer;
00266 waveOutHdr[i].lpData = new char[bytesPerBuffer];
00267 waveOutHdr[i].dwFlags = waveOutHdr[i].dwLoops = 0;
00268 waveOutPrepareHeader(waveOut, waveOutHdr + i, sizeof(WAVEHDR));
00269 }
00270 return true;
00271 }
00272
00273 void TWavePlayer::ClosePlayDevice(void)
00274 {
00275 int i;
00276
00277 waveOutReset(waveOut);
00278 for (i = 0; i < 3; i++)
00279 {
00280 waveOutUnprepareHeader(waveOut, waveOutHdr + i, sizeof(WAVEHDR));
00281 delete[] waveOutHdr[i].lpData;
00282 waveOutHdr[i].lpData = NULL;
00283 }
00284 waveOutClose(waveOut);
00285 }
00286
00287 bool TWavePlayer::Record(int maxDuration)
00288 {
00289 if (mode == RECORDING)
00290 return true;
00291
00292 StopPlay();
00293 Clear();
00294 if (!OpenRecordDevice())
00295 return false;
00296
00297 mode = RECORDING;
00298 duration = maxDuration;
00299 bufferTotal = (duration * GetSampleRate() + bufferSize - 1) / bufferSize;
00300 wave = new int[bufferTotal * bufferSize + 16000];
00301 waveInStart(waveIn);
00302
00303 if (duration == 0)
00304 {
00305 RecordComplete();
00306 return true;
00307 }
00308
00309 if (echoOn)
00310 {
00311 if (OpenPlayDevice())
00312 firstEcho = true;
00313 }
00314
00315 return true;
00316 }
00317
00318 void TWavePlayer::StopRecord(void)
00319 {
00320 if (mode != RECORDING)
00321 return;
00322
00323 mode = IDLE;
00324 bufferTotal = (waveSize + bufferSize - 1) / bufferSize;
00325 duration = (float)waveSize / GetSampleRate();
00326 CloseRecordDevice();
00327 if (echoOn)
00328 ClosePlayDevice();
00329 }
00330
00331 bool TWavePlayer::Play(void)
00332 {
00333 int i;
00334
00335 if (mode == PLAYING)
00336 return true;
00337
00338 StopRecord();
00339 if (!OpenPlayDevice())
00340 return false;
00341
00342 mode = PLAYING;
00343 playBufferCount = 0;
00344
00345 if (waveSize == 0)
00346 {
00347 PlayComplete();
00348 return true;
00349 }
00350
00351 WaveCopy(waveOutHdr[0].lpData, wave, bufferSize);
00352 if (waveSize > bufferSize)
00353 WaveCopy(waveOutHdr[1].lpData, wave + bufferSize, bufferSize);
00354
00355 waveOutWrite(waveOut, waveOutHdr, sizeof(WAVEHDR));
00356 if (waveSize > bufferSize)
00357 waveOutWrite(waveOut, waveOutHdr + 1, sizeof(WAVEHDR));
00358
00359 return true;
00360 }
00361
00362 void TWavePlayer::StopPlay(void)
00363 {
00364 if (mode != PLAYING)
00365 return;
00366
00367 mode = IDLE;
00368 ClosePlayDevice();
00369 }
00370
00371 void TWavePlayer::EchoOn(void)
00372 {
00373 if (echoOn)
00374 return;
00375
00376 echoOn = true;
00377 if (mode == RECORDING)
00378 if (OpenPlayDevice())
00379 firstEcho = true;
00380 }
00381
00382 void TWavePlayer::EchoOff(void)
00383 {
00384 if (!echoOn)
00385 return;
00386
00387 echoOn = false;
00388 if (mode == RECORDING)
00389 ClosePlayDevice();
00390 }
00391
00392 float TWavePlayer::GetDuration(void)
00393 {
00394 return duration;
00395 }
00396
00397 float TWavePlayer::GetTimeCode(void)
00398 {
00399 if (mode == IDLE || bufferTotal == 0)
00400 return 0;
00401 return (mode == RECORDING? recordBufferCount : playBufferCount) * duration / bufferTotal;
00402 }
00403
00404 void TWavePlayer::Seek(int percent)
00405 {
00406 if (mode != PLAYING)
00407 return;
00408
00409 playBufferCount = bufferTotal * percent / 100;
00410 }
00411
00412 void TWavePlayer::Clear()
00413 {
00414 delete[] wave;
00415 wave = NULL;
00416 waveSize = 0;
00417 duration = 0.0f;
00418 bufferTotal = recordBufferCount = playBufferCount = 0;
00419 }
00420
00421 void TWavePlayer::Trim(int from, int to)
00422 {
00423 int *newwave;
00424
00425 if (from < 0)
00426 from = 0;
00427 if (to >= waveSize)
00428 to = waveSize - 1;
00429 if (from > to)
00430 to = from - 1;
00431 waveSize = to - from + 1;
00432 duration = (float)waveSize / GetSampleRate();
00433 bufferTotal = (waveSize + bufferSize - 1) / bufferSize;
00434 newwave = new int[bufferTotal * bufferSize + 16000];
00435 memcpy(newwave, wave + from, waveSize * sizeof(int));
00436 memset(newwave + waveSize, 0, (bufferTotal * bufferSize + 16000 - waveSize) * sizeof(int));
00437 delete[] wave;
00438 wave = newwave;
00439 }
00440
00441 void TWavePlayer::RecordABuffer(void)
00442 {
00443 if (mode != RECORDING)
00444 return;
00445
00446 WaveCopy(wave + waveSize, waveInHdr[recordBufferCount % 3].lpData, bufferSize);
00447 waveSize += bufferSize;
00448
00449 ++recordBufferCount;
00450 if (recordBufferCount == bufferTotal)
00451 {
00452 PostMessage(HiddenWindow->Handle, WM_APP + 111, 0, 0);
00453 return;
00454 }
00455 if (mode == RECORDING)
00456 Deliver(EVENT_RECORD_BUFFER, wave + (recordBufferCount - 1) * bufferSize);
00457
00458 if (recordBufferCount < bufferTotal - 1)
00459 {
00460 if (echoOn && firstEcho)
00461 {
00462 firstEcho = false;
00463 firstEchoBufferIndex = recordBufferCount - 1;
00464 memset(waveOutHdr[0].lpData, bytesPerSample == 1? 128 : 0, bytesPerBuffer);
00465 memcpy(waveOutHdr[1].lpData, waveInHdr[(recordBufferCount + 2) % 3].lpData, bytesPerBuffer);
00466
00467 waveOutWrite(waveOut, waveOutHdr, sizeof(WAVEHDR));
00468 waveOutWrite(waveOut, waveOutHdr + 1, sizeof(WAVEHDR));
00469 }
00470
00471 waveInAddBuffer(waveIn, waveInHdr + (recordBufferCount + 1) % 3, sizeof(WAVEHDR));
00472 }
00473 }
00474
00475 void TWavePlayer::PlayABuffer(void)
00476 {
00477 WAVEHDR *waveHdr;
00478 int i, *ip3, vol;
00479 short *sp1, *sp2, *sp3;
00480 unsigned char *ucp1, *ucp2, *ucp3;
00481
00482 ++playBufferCount;
00483 if (playBufferCount == bufferTotal && mode == PLAYING)
00484 {
00485 PostMessage(HiddenWindow->Handle, WM_APP + 222, 0, 0);
00486 return;
00487 }
00488 if (mode == PLAYING)
00489 Deliver(EVENT_PLAY_BUFFER, wave + (playBufferCount - 1) * bufferSize);
00490
00491 if (playBufferCount == bufferTotal - 1)
00492 return;
00493
00494 waveHdr = waveOutHdr + (playBufferCount + 1) % 3;
00495 if (echoOn)
00496 {
00497 if (bytesPerSample == 1)
00498 {
00499 ucp1 = (unsigned char *)waveHdr->lpData;
00500 ucp2 = (unsigned char *)waveOutHdr[playBufferCount % 3].lpData;
00501 if (mode == RECORDING)
00502 {
00503 ucp3 = (unsigned char *)waveInHdr[(firstEchoBufferIndex + playBufferCount) % 3].lpData;
00504 for (i = bufferSize - 1; i >= 0; i--)
00505 {
00506 vol = (ucp2[i] - 128) * echoVolume / 10 + ucp3[i];
00507 if (vol > 255)
00508 ucp1[i] = 255;
00509 else if (vol < 0)
00510 ucp1[i] = 0;
00511 else
00512 ucp1[i] = vol;
00513 }
00514 }
00515 else
00516 {
00517 ip3 = wave + (playBufferCount + 1) * bufferSize;
00518 for (i = bufferSize - 1; i >= 0; i--)
00519 {
00520 vol = (ucp2[i] - 128) * echoVolume / 10 + ip3[i] + 128;
00521 if (vol > 255)
00522 ucp1[i] = 255;
00523 else if (vol < 0)
00524 ucp1[i] = 0;
00525 else
00526 ucp1[i] = vol;
00527 }
00528 }
00529 }
00530 else
00531 {
00532 sp1 = (short *)waveHdr->lpData;
00533 sp2 = (short *)waveOutHdr[playBufferCount % 3].lpData;
00534 if (mode == RECORDING)
00535 {
00536 sp3 = (short *)waveInHdr[(firstEchoBufferIndex + playBufferCount) % 3].lpData;
00537 for (i = bufferSize - 1; i >= 0; i--)
00538 {
00539 vol = sp2[i] * echoVolume / 10 + sp3[i];
00540 if (vol > 32767)
00541 sp1[i] = 32767;
00542 else if (vol < -32768)
00543 sp1[i] = -32768;
00544 else
00545 sp1[i] = vol;
00546 }
00547 }
00548 else
00549 {
00550 ip3 = wave + playBufferCount * bufferSize;
00551 for (i = bufferSize - 1; i >= 0; i--)
00552 {
00553 vol = sp2[i] * echoVolume / 10 + ip3[i];
00554 if (vol > 32767)
00555 sp1[i] = 32767;
00556 else if (vol < -32768)
00557 sp1[i] = -32768;
00558 else
00559 sp1[i] = vol;
00560 }
00561 }
00562 }
00563 waveOutWrite(waveOut, waveHdr, sizeof(WAVEHDR));
00564 }
00565 else if (mode == PLAYING)
00566 {
00567 WaveCopy(waveHdr->lpData, wave + (playBufferCount + 1) * bufferSize, bufferSize);
00568 waveOutWrite(waveOut, waveHdr, sizeof(WAVEHDR));
00569 }
00570 }
00571
00572 void TWavePlayer::RecordComplete(void)
00573 {
00574 StopRecord();
00575 Deliver(EVENT_RECORD_COMPLETE);
00576 }
00577
00578 void TWavePlayer::PlayComplete(void)
00579 {
00580 StopPlay();
00581 Deliver(EVENT_PLAY_COMPLETE);
00582 }
00583