comparison AudioPac.cpp @ 0:a6a46af64546

first upload
author wenx <xue.wen@eecs.qmul.ac.uk>
date Wed, 10 Aug 2011 14:55:38 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:a6a46af64546
1 /*
2 Harmonic Visualiser
3
4 An audio file viewer and editor.
5 Centre for Digital Music, Queen Mary, University of London.
6 This file copyright 2011 Wen Xue.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12 */
13 //---------------------------------------------------------------------------
14 #include <vcl.h>
15 #pragma hdrstop
16
17 #include "AudioPac.h"
18 #include <math.h>
19
20 #pragma package(smart_init)
21 //---------------------------------------------------------------------------
22 void DoubleToInt(void* out, int BytesPerSample, double* in, int Count)
23 {
24 if (BytesPerSample==1){unsigned char* out8=(unsigned char*)out; for (int k=0; k<Count; k++) *(out8++)=*(in++)+128.5;}
25 else if (BytesPerSample==2) {__int16* out16=(__int16*)out; for (int k=0; k<Count; k++) *(out16++)=floor(*(in++)+0.5);}
26 else {__pint24 out24=(__pint24)out; for (int k=0; k<Count; k++) {*(out24++)=floor(*(in++)+0.5);}}
27 }
28
29 void IntToDouble(double* out, void* in, int BytesPerSample, int Count)
30 {
31 if (BytesPerSample==1){unsigned char* in8=(unsigned char*)in; for (int k=0; k<Count; k++) *(out++)=*(in8++)-128.0;}
32 else if (BytesPerSample==2) {__int16* in16=(__int16*)in; for (int k=0; k<Count; k++) *(out++)=*(in16++);}
33 else {__pint24 in24=(__pint24)in; for (int k=0; k<Count; k++) {*(out++)=*(in24++);}}
34 }
35
36 void DoubleToIntInterleave(void* out, int BytesPerSample, double* in1, double* in2, int Count)
37 {
38 if (BytesPerSample==1)
39 {
40 unsigned char* out8=(unsigned char*)out;
41 for (int k=0; k<Count; k++) {*(out8++)=*(in1++)+128; *(out8++)=*(in2++)+128;}
42 }
43 else if (BytesPerSample==2)
44 {
45 __int16* out16=(__int16*)out;
46 for (int k=0; k<Count; k++) {*(out16++)=*(in1++); *(out16++)=*(in2++);}
47 }
48 else if (BytesPerSample==3)
49 {
50 __pint24 out24=(__pint24)out;
51 for (int k=0; k<Count; k++) {*(out24++)=*(in1++); *(out24++)=*(in2++); }
52 }
53 }
54
55 void IntToDoubleInterleave(double* out1, double* out2, void* in, int BytesPerSample, int Count)
56 {
57 if (BytesPerSample==1)
58 {
59 unsigned char* in8=(unsigned char*)in;
60 for (int k=0; k<Count; k++) {*(out1++)=*(in8++)-128.0; *(out2++)=*(in8++)-128.0;}
61 }
62 else if (BytesPerSample==2)
63 {
64 __int16* in16=(__int16*)in;
65 for (int k=0; k<Count; k++) {*(out1++)=*(in16++); *(out2++)=*(in16++);}
66 }
67 else if (BytesPerSample==3)
68 {
69 __pint24 in24=(__pint24)in;
70 for (int k=0; k<Count; k++) {*(out1++)=*(in24++); *(out2++)=*(in24++);}
71 }
72 }
73
74 int IntToIntInterleave(void* dest, int bytesperunit, void* block1, void* block2, int Count)
75 {
76 if (bytesperunit==1)
77 {
78 char* Dest=(char*)dest;
79 char* Block1=(char*)block1;
80 char* Block2=(char*)block2;
81 for (int i=0; i<Count; i++)
82 {
83 *(Dest++)=*(Block1++);
84 *(Dest++)=*(Block2++);
85 }
86 return 2*Count;
87 }
88 else if (bytesperunit==2)
89 {
90 __int16* Dest=(__int16*)dest;
91 __int16* Block1=(__int16*)block1;
92 __int16* Block2=(__int16*)block2;
93 for (int i=0; i<Count; i++)
94 {
95 *(Dest++)=*(Block1++);
96 *(Dest++)=*(Block2++);
97 }
98 return 4*Count;
99 }
100 else if (bytesperunit==3)
101 {
102 __pint24 Dest=(__pint24)dest;
103 __pint24 Block1=(__pint24)block1;
104 __pint24 Block2=(__pint24)block2;
105 for (int i=0; i<Count; i++)
106 {
107 *(Dest++)=*(Block1++);
108 *(Dest++)=*(Block2++);
109 }
110 return 6*Count;
111 }
112 else
113 return 0;
114 }
115
116 int IntToIntInterleave(void* dest1, void* dest2, int bytesperunit, void* block, int Count)
117 {
118 if (bytesperunit==1)
119 {
120 char* Dest1=(char*)dest1;
121 char* Dest2=(char*)dest2;
122 char* Block=(char*)block;
123 for (int i=0; i<Count; i++)
124 {
125 *(Dest1++)=*(Block++);
126 *(Dest2++)=*(Block++);
127 }
128 return 2*Count;
129 }
130 else if (bytesperunit==2)
131 {
132 __int16* Dest1=(__int16*)dest1;
133 __int16* Dest2=(__int16*)dest2;
134 __int16* Block=(__int16*)block;
135 for (int i=0; i<Count; i++)
136 {
137 *(Dest1++)=*(Block++);
138 *(Dest2++)=*(Block++);
139 }
140 return 4*Count;
141 }
142 else if (bytesperunit==2)
143 {
144 __pint24 Dest1=(__pint24)dest1;
145 __pint24 Dest2=(__pint24)dest2;
146 __pint24 Block=(__pint24)block;
147 for (int i=0; i<Count; i++)
148 {
149 *(Dest1++)=*(Block++);
150 *(Dest2++)=*(Block++);
151 }
152 return 6*Count;
153 }
154 else
155 return 0;
156 }
157
158 int IntToIntMultiSingle(void* dest, int bytesperunit, int channels, int offset, void* block, int Count)
159 {
160 if (channels==1)
161 {
162 memcpy(dest, &((char*)block)[offset*bytesperunit], bytesperunit*Count);
163 return Count;
164 }
165 else if (channels==2)
166 {
167 if (bytesperunit==1)
168 {
169 char* Dest=(char*)dest;
170 char* Block=&((char*)block)[offset];
171 for (int i=0; i<Count; i++)
172 {
173 *(Dest++)=*Block;
174 Block+=2;
175 }
176 return Count;
177 }
178 else if (bytesperunit==2)
179 {
180 __int16* Dest=(__int16*)dest;
181 __int16* Block=(__int16*)(&((char*)block)[offset*2]);
182 for (int i=0; i<Count; i++)
183 {
184 *(Dest++)=*Block;
185 Block+=2;
186 }
187 return Count*2;
188 }
189 else if (bytesperunit==3)
190 {
191 __pint24 Dest=(__pint24)dest;
192 __pint24 Block=(__pint24)(&((char*)block)[offset*3]);
193 for (int i=0; i<Count; i++)
194 {
195 *(Dest++)=*Block;
196 Block+=2;
197 }
198 return Count*3;
199 }
200 else
201 return 0;
202 }
203 else
204 {
205 if (bytesperunit==1)
206 {
207 char* Dest=(char*)dest;
208 char* Block=&((char*)block)[offset];
209 for (int i=0; i<Count; i++)
210 {
211 *(Dest++)=*Block;
212 Block+=channels;
213 }
214 return Count;
215 }
216 else if (bytesperunit==2)
217 {
218 __int16* Dest=(__int16*)dest;
219 __int16* Block=(__int16*)(&((char*)block)[offset*2]);
220 for (int i=0; i<Count; i++)
221 {
222 *(Dest++)=*Block;
223 Block+=channels;
224 }
225 return Count*2;
226 }
227 else if (bytesperunit==3)
228 {
229 __pint24 Dest=(__pint24)dest;
230 __pint24 Block=(__pint24)(&((char*)block)[offset*3]);
231 for (int i=0; i<Count; i++)
232 {
233 *(Dest++)=*Block;
234 Block+=channels;
235 }
236 return Count*3;
237 }
238 else return 0;
239 }
240 }
241
242 int IntToIntMultiChannel(int C, void** dest, int bytesperunit, int channels, void* block, int count)
243 {
244 int tail=channels-C;
245 if (bytesperunit==1)
246 {
247 char* data=(char*)block;
248 for (int i=0; i<count; i++)
249 {
250 for (int c=0; c<C; c++) *(((char*)dest[c])++)=*(data++);
251 data=&data[tail];
252 }
253 return count;
254 }
255 else if (bytesperunit==2)
256 {
257 __int16* data=(__int16*)block;
258 for (int i=0; i<count; i++)
259 {
260 for (int c=0; c<C; c++) *(((__int16*)dest[c])++)=*(data++);
261 data=&data[tail];
262 }
263 return count*2;
264 }
265 else if (bytesperunit==3)
266 {
267 __pint24 data=(__pint24)block;
268 for (int i=0; i<count; i++)
269 {
270 for (int c=0; c<C; c++) {*(((__pint24)dest[c])++)=*(data++); }
271 data=&data[tail];
272 }
273 return count*3;
274 }
275 else
276 return 0;
277 }
278
279 __fastcall TAttachFileStream::TAttachFileStream(TFileStream* AFile)
280 : TStream()
281 {
282 File=AFile;
283 StartOffset=0;
284 EndOffset=0;
285 }
286
287 __fastcall TAttachFileStream::~TAttachFileStream()
288 {
289 delete File;
290 }
291
292 int __fastcall TAttachFileStream::Read(void *Buffer, int Count)
293 {
294 return File->Read(Buffer, Count);
295 }
296
297 int __fastcall TAttachFileStream::Seek(int AnOffset, Word Origin)
298 {
299 if (!File) return 0;
300 if (Origin==soFromBeginning)
301 return File->Seek(AnOffset+StartOffset, soFromBeginning)-StartOffset;
302 else if (Origin==soFromCurrent)
303 return File->Seek(AnOffset, soFromCurrent)-StartOffset;
304 else
305 return File->Seek(AnOffset+EndOffset, soFromEnd)-StartOffset;
306 }
307
308 __int64 __fastcall TAttachFileStream::Seek(const __int64 AnOffset, TSeekOrigin Origin)
309 {
310 return Seek((int)AnOffset, (Word)Origin);
311 }
312
313 int __fastcall TAttachFileStream::Write(const void *Buffer, int Count)
314 {
315 return File->Write(Buffer, Count);
316 }
317
318 //---------------------------------------------------------------------------
319 // ValidCtrCheck is used to assure that the components created do not have
320 // any pure virtual functions.
321 //
322
323 static inline void ValidCtrCheck(TWaveAudio *)
324 {
325 new TWaveAudio(NULL);
326 }
327 //---------------------------------------------------------------------------
328 __fastcall TWaveAudio::~TWaveAudio()
329 {
330 delete FMemoryStream;
331 delete FFileStream;
332 DeallocateHWnd(HWndOut);
333 DeallocateHWnd(HWndIn);
334 }
335
336 //---------------------------------------------------------------------------
337 void __fastcall TWaveAudio::Clear(TObject* Sender)
338 {
339 if (!FUseMemoryStream)
340 {
341 FUseMemoryStream=true;
342 delete FFileStream->File;
343 FFileStream->File=0;
344 FFileName="";
345 }
346 FMemoryStream->Position=0;
347 FMemoryStream->Size=0;
348 if (FOnAudioChange) FOnAudioChange(this);
349 }
350
351 //---------------------------------------------------------------------------
352 void __fastcall TWaveAudio::CloseFile(bool Close)
353 {
354 if (UseMemoryStream) return;
355 int Position=FFileStream->Position;
356 delete FFileStream->File;
357 FFileStream->File=new TFileStream(FFileName, fmOpenWrite);
358 SaveHeader(FFileStream->File);
359 delete FFileStream->File;
360 FFileStream->File=0;
361 if (!Close)
362 {
363 FFileStream->File=new TFileStream(FFileName, fmOpenRead);
364 FFileStream->Position=Position;
365 }
366 }
367
368 //---------------------------------------------------------------------------
369 void TWaveAudio::CopyFrom(TStream* AStream, int Count)
370 {
371 WaveStream->CopyFrom(AStream, Count);
372 if (FOnAudioChange) FOnAudioChange(this);
373 }
374
375 void TWaveAudio::CopyFrom(TWaveAudio* AWaveAudio, int Count)
376 {
377 WaveStream->CopyFrom(AWaveAudio->WaveStream, Count);
378 if (FOnAudioChange) FOnAudioChange(this);
379 }
380
381 //---------------------------------------------------------------------------
382 void TWaveAudio::CopySamplesFrom(TStream* AStream, int Count)
383 {
384 WaveStream->CopyFrom(AStream, Count*FChannels*(BitsPerSample/8));
385 if (FOnAudioChange) FOnAudioChange(this);
386 }
387
388 void TWaveAudio::CopySamplesFrom(TWaveAudio* AWaveAudio, int Count)
389 {
390 WaveStream->CopyFrom(AWaveAudio->WaveStream, Count*FChannels*(BitsPerSample/8));
391 if (FOnAudioChange) FOnAudioChange(this);
392 }
393
394 //---------------------------------------------------------------------------
395 void TWaveAudio::CreateFile(AnsiString FileName)
396 {
397 UseMemoryStream=false;
398
399 TFileStream* OpenFile=new TFileStream(FileName, fmCreate);
400 SaveHeader(OpenFile);
401 delete OpenFile;
402
403 delete FFileStream->File;
404 FFileStream->File=new TFileStream(FileName, fmOpenReadWrite);
405 FFileStream->StartOffset=FFileStream->File->Size;
406 FFileStream->Position=0;
407 FFileName=FileName;
408 }
409
410 //---------------------------------------------------------------------------
411 int __fastcall TWaveAudio::FillBlock(void* Block)
412 {
413 return Stream->Read(Block, FBlockSize);
414 }
415
416 //---------------------------------------------------------------------------
417 int __fastcall TWaveAudio::GetBytesPerSample()
418 {
419 return FBitsPerSample/8;
420 }
421
422 //---------------------------------------------------------------------------
423 __int32 __fastcall TWaveAudio::GetLength()
424 {
425 return Stream->Size/FBlockAlign;
426 }
427
428 //---------------------------------------------------------------------------
429 TStream* __fastcall TWaveAudio::GetStream()
430 {
431 if (FUseMemoryStream) return FMemoryStream;
432 else return FFileStream;
433 }
434
435 //---------------------------------------------------------------------------
436 void TWaveAudio::GetWaveProperties(TWaveAudio* WaveAudio1)
437 {
438 FFormatTag=WaveAudio1->FormatTag;
439 SamplesPerSec=WaveAudio1->SamplesPerSec;
440 BitsPerSample=WaveAudio1->BitsPerSample;
441 Channels=WaveAudio1->Channels;
442 BlockSize=WaveAudio1->BlockSize;
443 }
444
445 //---------------------------------------------------------------------------
446 bool __fastcall TWaveAudio::ReadHeader(TStream* AStream, __int32& length, bool allowunfinisheddata)
447 {
448 bool success=true;
449 char s[10];
450 __int32 headerlen;
451 __int32 headerstart;
452
453 __int16 formattag;
454 __int16 channels;
455 __int32 samplespersec;
456 __int32 avgbytespersec;
457 __int16 blockalign;
458 __int16 bitspersample;
459
460 int rc=AStream->Read(s, 4); s[4]=0;
461 success=success&&(rc==4)&&!strcmp(s, "RIFF");
462 if (!success) return success;
463
464 rc=AStream->Read(&length, 4);
465 success=success&&(rc==4);
466
467 rc=AStream->Read(s, 4); if (rc!=4) return false;
468 s[4]=0;
469 success=success&&(rc==4)&&!strcmp(s, "WAVE");
470 if (!success) return success;
471
472 rc=AStream->Read(s, 4); s[4]=0;
473 while(rc==4 && strcmp(s, "fmt "))
474 {
475 AStream->Read(&length, 4);
476 AStream->Seek(length, soFromCurrent);
477 rc=AStream->Read(s, 4); s[4]=0;
478 }
479 success=success&&(rc==4);
480 if (!success) return success;
481
482 rc=AStream->Read(&headerlen, 4);
483 headerstart=AStream->Position;
484
485 AStream->Read(&formattag, 2);
486 AStream->Read(&channels, 2);
487 AStream->Read(&samplespersec, 4);
488 AStream->Read(&avgbytespersec, 4);
489 AStream->Read(&blockalign, 2);
490 AStream->Read(&bitspersample, 2);
491 success=success&&(formattag==1);
492 success=success&&(rc==4)&&(blockalign*8==channels*bitspersample);
493 success=success&&(avgbytespersec==samplespersec*blockalign);
494
495 if (!success) return success;
496 AStream->Seek(headerlen+headerstart, soFromBeginning);
497
498 rc=AStream->Read(s, 4); s[4]=0;
499 while(rc==4 && strcmp(s, "data"))
500 {
501 AStream->Read(&length, 4);
502 AStream->Seek(length, soFromCurrent);
503 rc=AStream->Read(s, 4); s[4]=0;
504 }
505 success=success&&(rc==4);
506 if (!success) return success;
507
508 rc=AStream->Read(&length, 4);
509 success=success&&(rc==4);
510 if (!success) return success;
511
512 if (AStream->Position+length>AStream->Size)
513 {
514 if (allowunfinisheddata) length=(AStream->Size-AStream->Position)/blockalign*blockalign;
515 else success=false;
516 }
517 if (!success) return success;
518
519 FFormatTag=formattag;
520 FChannels=channels;
521 FSamplesPerSec=samplespersec;
522 FAvgBytesPerSec=avgbytespersec;
523 FBlockAlign=blockalign;
524 FBitsPerSample=bitspersample;
525
526 return success;
527 }
528
529 void TWaveAudio::InsertFromFile(AnsiString FileName)
530 {
531 TFileStream* OpenFile=new TFileStream(FileName, fmOpenRead|fmShareDenyNone);
532
533 __int32 length;
534 bool success=ReadHeader(OpenFile, length);
535
536 if (success)
537 {
538 FFileName=FileName;
539 if (FUseMemoryStream)
540 {
541 if (length>0)
542 {
543 FMemoryStream->Size=length;
544 OpenFile->Read(FMemoryStream->Memory, length);
545 }
546 delete OpenFile;
547 }
548 else
549 {
550 delete FFileStream->File;
551 FFileStream->File=OpenFile;
552 FFileStream->StartOffset=OpenFile->Position;
553 FFileStream->EndOffset=OpenFile->Position+length-OpenFile->Size;
554 }
555
556 if (FStreamLimit>0 && Stream->Size>=FStreamLimit && OnStreamFull) OnStreamFull(this);
557 if (FOnAudioChange) FOnAudioChange(this);
558 }
559 else
560 {
561 delete OpenFile;
562 throw EReadError("PCM error ecountered reading "+FileName);
563 }
564 }
565
566 //---------------------------------------------------------------------------
567 bool TWaveAudio::IsValidWave(AnsiString FileName)
568 {
569 bool success=true;
570 char s[10];
571 __int32 headerlen;
572 __int32 headerstart;
573
574 __int16 formattag;
575 __int16 channels;
576 __int32 samplespersec;
577 __int32 avgbytespersec;
578 __int16 blockalign;
579 __int16 bitspersample;
580 __int32 length;
581
582
583 TFileStream* OpenFile=new TFileStream(FileName,fmOpenRead|fmShareDenyNone);
584
585 OpenFile->Read(s, 4);
586 s[4]=0;
587 success=success&&!strcmp(s, "RIFF");
588
589 OpenFile->Read(&length, 4);
590 success=success&&(length+OpenFile->Position==OpenFile->Size);
591
592 OpenFile->Read(s, 8);
593 s[8]=0;
594 success=success&&!strcmp(s, "WAVEfmt ");
595
596 OpenFile->Read(&headerlen, 4);
597 headerstart=OpenFile->Position;
598
599 OpenFile->Read(&formattag, 2);
600 success=success&&(formattag==1);
601
602 OpenFile->Read(&channels, 2);
603 OpenFile->Read(&samplespersec, 4);
604 OpenFile->Read(&avgbytespersec, 4);
605 OpenFile->Read(&blockalign, 2);
606 OpenFile->Read(&bitspersample, 2);
607 success=success&&(blockalign*8==channels*bitspersample);
608 success=success&&(avgbytespersec==samplespersec*blockalign);
609
610 OpenFile->Seek(headerlen+headerstart, soFromBeginning);
611 OpenFile->Read(s, 4);
612 s[4]=0;
613 success=success&&!strcmp(s, "data");
614
615 OpenFile->Read(&length, 4);
616 success=success&&(length+OpenFile->Position==OpenFile->Size);
617
618 delete OpenFile;
619 return success;
620 }
621
622 //---------------------------------------------------------------------------
623 void TWaveAudio::LoadFromFile(AnsiString FileName)
624 {
625 if (FOnBeforeLoad) FOnBeforeLoad(this);
626 if (FAutoUseMemoryStream) UseMemoryStream=false;
627 if (FUseMemoryStream) FMemoryStream->Clear();
628 InsertFromFile(FileName);
629 if (FOnLoad) FOnLoad(this);
630 }
631
632 //---------------------------------------------------------------------------
633 void __fastcall TWaveAudio::OnWimClose(TMessage& Message)
634 {
635 waveInUnprepareHeader(WaveIn,WaveHdr1,sizeof(WAVEHDR));
636 waveInUnprepareHeader(WaveIn,WaveHdr2,sizeof(WAVEHDR));
637 delete WaveHdr1;
638 delete WaveHdr2;
639 delete[] Buffer1;
640 delete[] Buffer2;
641 FRecording=false;
642 if (ResetInStream && FOnStreamFull)
643 FOnStreamFull(this);
644 ResetInStream=false;
645 ResetInUser=false;
646 if (FOnRecordingDone) FOnRecordingDone(this);
647 if (FOnAudioChange) FOnAudioChange(this);
648 }
649
650 //---------------------------------------------------------------------------
651 void __fastcall TWaveAudio::OnWimData(TMessage& Message)
652 {
653 WAVEHDR* WaveHdr=(WAVEHDR*)Message.LParam;
654 if (!FRecording) return;
655
656 if (!ResetInStream)
657 {
658 ReleaseBlock(WaveHdr->lpData,WaveHdr->dwBytesRecorded);
659 if (FStreamLimit>0 && Stream->Size>=FStreamLimit)
660 ResetInStream=true;
661 waveInAddBuffer(WaveIn,WaveHdr,sizeof(WAVEHDR));
662 if (FOnInAddBuffer) FOnInAddBuffer(this);
663 if (ResetInUser)
664 {
665 waveInReset(WaveIn);
666 waveInClose(WaveIn);
667 }
668 }
669 else
670 {
671 waveInReset(WaveIn);
672 waveInClose(WaveIn);
673 }
674 }
675
676 //---------------------------------------------------------------------------
677 void __fastcall TWaveAudio::OnWimOpen(TMessage& Message)
678 {
679 //
680 }
681
682 //---------------------------------------------------------------------------
683 void __fastcall TWaveAudio::OnWomClose(TMessage& Message)
684 {
685 waveOutUnprepareHeader(WaveOut,WaveHdr1,sizeof(WAVEHDR));
686 waveOutUnprepareHeader(WaveOut,WaveHdr2,sizeof(WAVEHDR));
687 delete WaveHdr1;
688 delete WaveHdr2;
689 delete[] Buffer1;
690 delete[] Buffer2;
691 WaveHdr1=WaveHdr2=0;
692 Buffer1=Buffer2=0;
693 FPlaying=false;
694 FPaused=false;
695 ResetOut=false;
696 ResetOutUser=false;
697 if (FOnPlaybackProgress) FOnPlaybackProgress(this, 1);
698 if (FOnPlaybackProg) FOnPlaybackProg(this, -2);
699
700 if (OnPlaybackDone) OnPlaybackDone(this);
701 }
702
703 //---------------------------------------------------------------------------
704 void __fastcall TWaveAudio::OnWomDone(TMessage& Message)
705 {
706 WAVEHDR* WaveHdr=(WAVEHDR*)Message.LParam;
707
708 if (ResetOut)
709 {
710 if (WaveHdr->dwBufferLength!=(unsigned)FBlockSize)
711 {
712 waveOutClose(WaveOut);
713 }
714 }
715 else
716 {
717 int rc;
718
719 if (ResetOutUser) rc=0;
720 else rc=FillBlock(WaveHdr->lpData);
721
722 if (rc!=FBlockSize)
723 {
724 ResetOut=true;
725 WaveHdr->dwBufferLength=rc;
726 if (BitsPerSample==8) memset(&WaveHdr->lpData[rc],0x80,FBlockSize-rc);
727 else memset(&WaveHdr->lpData[rc],0,FBlockSize-rc);
728 waveOutUnprepareHeader(WaveOut, WaveHdr, sizeof(WAVEHDR));
729 waveOutPrepareHeader(WaveOut, WaveHdr, sizeof(WAVEHDR));
730 }
731 waveOutWrite(WaveOut,WaveHdr,sizeof(WAVEHDR));
732 if (FOnPlaybackProgress)
733 FOnPlaybackProgress(this, (Stream->Position-FBlockSize)*1.0/Stream->Size);
734 if (FOnPlaybackProg)
735 FOnPlaybackProg(this, Stream->Position-FBlockSize);
736 if (FOnOutWrite) FOnOutWrite(this);
737 }
738 }
739
740 //---------------------------------------------------------------------------
741 void __fastcall TWaveAudio::OnWomOpen(TMessage& Message)
742 {
743 //
744 }
745
746 //---------------------------------------------------------------------------
747 void __fastcall TWaveAudio::Pause(TObject* Sender)
748 {
749 if (FPlaying)
750 {
751 waveOutPause(WaveOut);
752 FPaused=true;
753 }
754 }
755
756 //---------------------------------------------------------------------------
757 void __fastcall TWaveAudio::PausePlayback(TObject* Sender)
758 {
759 if (Playing) ResetOutUser=true;
760 }
761
762 //---------------------------------------------------------------------------
763 void __fastcall TWaveAudio::PauseRecording(TObject* Sender)
764 {
765 if (Recording) ResetInUser=true;
766 }
767
768 //---------------------------------------------------------------------------
769 void __fastcall TWaveAudio::Play(TObject* Sender)
770 {
771 Rewind(this);
772 StartPlayback(this);
773 }
774
775 void __fastcall TWaveAudio::Play(TNotifyEvent AnOnPlaybackDone)
776 {
777 Rewind(this);
778 OnPlaybackDone=AnOnPlaybackDone;
779 StartPlayback(this);
780 }
781
782 //---------------------------------------------------------------------------
783 int __fastcall TWaveAudio::Read(void* Buffer, int Count)
784 {
785 return Stream->Read(Buffer, Count);
786 }
787
788 int __fastcall TWaveAudio::ReadSamples(void* Buffer, int Count)
789 {
790 return Stream->Read(Buffer, Count*FChannels*(BitsPerSample/8));
791 }
792
793 int __fastcall TWaveAudio::ReadSamples(double* Buffer, int Count)
794 {
795 int FBytesPerSample=FBitsPerSample/8;
796 int countavailable=(Stream->Size-Stream->Position)/FBytesPerSample;
797 if (Count>countavailable) Count=countavailable;
798 if (FUseMemoryStream)
799 {
800 int Position=FMemoryStream->Position;
801 IntToDouble(Buffer, &((char*)FMemoryStream->Memory)[Position], FBytesPerSample, Count);
802 FMemoryStream->Position=Position+Count*FBytesPerSample;
803 }
804 else
805 {
806 void *data=new char[FBlockSize];
807 double *Data=Buffer;
808 int CountPF=FBlockSize/FBytesPerSample;
809 int Fr=(Count/CountPF);
810 for (int i=0; i<Fr; i++)
811 {
812 Stream->Read(data, FBlockSize);
813 IntToDouble(Data, data, FBytesPerSample, CountPF);
814 Data=&Data[CountPF];
815 }
816 int CountLastF=Count%CountPF;
817 int lastblocksize=CountLastF*FBytesPerSample;
818 Stream->Read(data, lastblocksize);
819 IntToDouble(Data, data, FBytesPerSample, CountLastF);
820 delete[] data;
821 }
822
823 return Count*FBytesPerSample;
824 }
825
826 int __fastcall TWaveAudio::ReadSamplesInterleave(void* Buffer1, void* Buffer2, int Count)
827 {
828 int FBytesPerSample=FBitsPerSample/8;
829 int SampleSize=FBytesPerSample*2;
830 int countavailable=(Stream->Size-Stream->Position)/SampleSize;
831 if (Count>countavailable) Count=countavailable;
832 if (FUseMemoryStream)
833 {
834 int Position=FMemoryStream->Position;
835 IntToIntInterleave(Buffer1, Buffer2, FBytesPerSample, &((char*)FMemoryStream->Memory)[Position], Count);
836 FMemoryStream->Position=Position+Count*SampleSize;
837 }
838 else
839 {
840 void *Data1=Buffer1, *Data2=Buffer2, *data=new char[FBlockSize];
841 int HBlockSize=FBlockSize/2, CountPF=FBlockSize/SampleSize;
842 int Fr=Count/CountPF;
843 for (int i=0; i<Fr; i++)
844 {
845 Stream->Read(data, FBlockSize);
846 IntToIntInterleave(Data1, Data2, FBytesPerSample, data, CountPF);
847 Data1=&((char*)Data1)[HBlockSize], Data2=&((char*)Data2)[HBlockSize];
848 }
849 int CountLastF=Count%CountPF;
850 int lastblocksize=CountLastF*SampleSize;
851 Stream->Read(data, lastblocksize);
852 IntToIntInterleave(Data1, Data2, FBytesPerSample, data, CountLastF);
853 delete[] data;
854 }
855 return Count*SampleSize;
856 }
857
858 int __fastcall TWaveAudio::ReadSamplesInterleave(double* Buffer1, double* Buffer2, int Count)
859 {
860 int FBytesPerSample=FBitsPerSample/8;
861 int SampleSize=FBytesPerSample*2;
862 int countavailable=(Stream->Size-Stream->Position)/SampleSize;
863 if (Count>countavailable) Count=countavailable;
864 if (FUseMemoryStream)
865 {
866 int Position=FMemoryStream->Position;
867 IntToDoubleInterleave(Buffer1, Buffer2, &((char*)FMemoryStream->Memory)[Position], FBytesPerSample, Count);
868 FMemoryStream->Position=Position+Count*SampleSize;
869 }
870 else
871 {
872 double *Data1=Buffer1, *Data2=Buffer2;
873 void *data=new char[FBlockSize];
874 int CountPF=FBlockSize/SampleSize;
875 int Fr=Count/CountPF;
876 for (int i=0; i<Fr; i++)
877 {
878 Stream->Read(data, FBlockSize);
879 IntToDoubleInterleave(Data1, Data2, data, FBytesPerSample, CountPF);
880 Data1=&Data1[CountPF], Data2=&Data2[CountPF];
881 }
882 int CountLastF=Count%CountPF;
883 int lastblocksize=CountLastF*SampleSize;
884 Stream->Read(data, lastblocksize);
885 IntToDoubleInterleave(Data1, Data2, data, FBytesPerSample, CountLastF);
886 delete[] data;
887 }
888 return Count*SampleSize;
889 }
890
891 int __fastcall TWaveAudio::ReadSamplesMultiSingle(void* Buffer, int Channel, int Count)
892 {
893 int FBytesPerSample=FBitsPerSample/8;
894 int SampleSize=FBytesPerSample*FChannels;
895 int countavailable=(Stream->Size-Stream->Position)/SampleSize;
896 if (Count>countavailable) Count=countavailable;
897 if (FUseMemoryStream)
898 {
899 int Position=FMemoryStream->Position;
900 IntToIntMultiSingle(Buffer, FBytesPerSample, FChannels, Channel, &((char*)FMemoryStream->Memory)[Position], Count);
901 FMemoryStream->Position=Position+Count*SampleSize;
902 }
903 else
904 {
905 int CountPF=FBlockSize/SampleSize;
906 int ReadSize=CountPF*SampleSize, WriteSize=CountPF*FBytesPerSample;
907 int Fr=Count/CountPF;
908 void *Data=Buffer, *data=new char[ReadSize];
909 for (int i=0; i<Fr; i++)
910 {
911 Stream->Read(data, ReadSize);
912 IntToIntMultiSingle(Data, FBytesPerSample, FChannels, Channel, data, CountPF);
913 Data=&((char*)Data)[WriteSize];
914 }
915 int CountLastF=Count%CountPF;
916 ReadSize=CountLastF*SampleSize;
917 Stream->Read(data, ReadSize);
918 IntToIntMultiSingle(Data, FBytesPerSample, FChannels, Channel, data, CountLastF);
919 delete[] data;
920 }
921 return Count*FBytesPerSample;
922 }
923
924 int __fastcall TWaveAudio::ReadSamplesMultiChannel(int C, void** Buffer, int Count)
925 {
926 if (C>FChannels) C=FChannels;
927 int FBytesPerSample=FBitsPerSample/8;
928 int SampleSize=FBytesPerSample*FChannels;
929 int countavailable=(Stream->Size-Stream->Position)/SampleSize;
930 if (Count>countavailable) Count=countavailable;
931 if (FUseMemoryStream)
932 {
933 int Position=FMemoryStream->Position;
934 IntToIntMultiChannel(C, Buffer, FBytesPerSample, FChannels, &((char*)FMemoryStream->Memory)[Position], Count);
935 FMemoryStream->Position=Position+Count*SampleSize;
936 }
937 else
938 {
939 int CountPF=FBlockSize/SampleSize;
940 int ReadSize=CountPF*SampleSize, WriteSize=CountPF*FBytesPerSample;
941 int Fr=Count/CountPF;
942 void* data=new char[ReadSize];
943 for (int i=0; i<Fr; i++)
944 {
945 Stream->Read(data, ReadSize);
946 IntToIntMultiChannel(C, Buffer, FBytesPerSample, FChannels, data, CountPF);
947 for (int c=0; c<C; c++) Buffer[c]=&((char*)Buffer[c])[WriteSize];
948 }
949 int CountLastF=Count*CountPF;
950 ReadSize=CountLastF*SampleSize;
951 Stream->Read(data, ReadSize);
952 IntToIntMultiChannel(C, Buffer, FBytesPerSample, FChannels, data, CountLastF);
953 }
954 return Count*SampleSize;
955 }
956
957 //---------------------------------------------------------------------------
958 void __fastcall TWaveAudio::ReleaseBlock(void* Block, int BytesRecorded)
959 {
960 Stream->Write(Block, BytesRecorded);
961 }
962
963 //---------------------------------------------------------------------------
964 void __fastcall TWaveAudio::Restart(TObject* Sender)
965 {
966 if (FPlaying)
967 {
968 waveOutRestart(WaveOut);
969 FPaused=false;
970 }
971 }
972
973 //---------------------------------------------------------------------------
974 void __fastcall TWaveAudio::Rewind(TObject* Sender)
975 {
976 Stream->Seek(0,soFromBeginning);
977 }
978
979 //---------------------------------------------------------------------------
980 void __fastcall TWaveAudio::SaveHeader(TStream* AStream)
981 {
982 __int32 s32;
983 __int16 s16;
984
985 AStream->Write("RIFF",4);
986 s32=Stream->Size+38;
987 AStream->Write(&s32,4);
988 AStream->Write("WAVEfmt ",8);
989 s32=0x12;
990 AStream->Write(&s32,4);
991 s16=FFormatTag;
992 AStream->Write(&s16,2);
993 s16=FChannels;
994 AStream->Write(&s16,2);
995 s32=FSamplesPerSec;
996 AStream->Write(&s32,4);
997 s32=FAvgBytesPerSec;
998 AStream->Write(&s32,4);
999 s16=FBlockAlign;
1000 AStream->Write(&s16,2);
1001 s16=FBitsPerSample;
1002 AStream->Write(&s16,2);
1003 s16=0;
1004 AStream->Write(&s16,2);
1005 AStream->Write("data",4);
1006 s32=Stream->Size;
1007 AStream->Write(&s32,4);
1008 }
1009
1010 void __fastcall TWaveAudio::SaveToFile(AnsiString FileName)
1011 {
1012 TFileStream& SaveFile=*new TFileStream(FileName, fmCreate);
1013 SaveHeader(&SaveFile);
1014
1015 if (FUseMemoryStream)
1016 ((TMemoryStream*)Stream)->SaveToStream(&SaveFile);
1017 else
1018 SaveFile.CopyFrom(Stream, 0);
1019 delete &SaveFile;
1020 }
1021
1022 //---------------------------------------------------------------------------
1023 void __fastcall TWaveAudio::Seek(int Offset, WORD Origin)
1024 {
1025 WaveStream->Seek(Offset, Origin);
1026 }
1027
1028 void __fastcall TWaveAudio::SeekSamples(int Offset, WORD Origin)
1029 {
1030 WaveStream->Seek(Offset*FChannels*(BitsPerSample/8), Origin);
1031 }
1032
1033 //---------------------------------------------------------------------------
1034 void __fastcall TWaveAudio::SetBitsPerSample(__int16 ABitsPerSample)
1035 {
1036 if (ABitsPerSample!=8 && ABitsPerSample!=16 && ABitsPerSample!=24) return;
1037 FBitsPerSample=ABitsPerSample;
1038 FAvgBytesPerSec=FSamplesPerSec*FBitsPerSample*FChannels/8;
1039 FBlockAlign=FBitsPerSample*FChannels/8;
1040 }
1041
1042 //---------------------------------------------------------------------------
1043 void __fastcall TWaveAudio::SetBlockSize(int ABlockSize)
1044 {
1045 FBlockSize=ABlockSize;
1046 }
1047
1048 //---------------------------------------------------------------------------
1049 void __fastcall TWaveAudio::SetChannels(__int16 AChannels)
1050 {
1051 if (AChannels!=1 && AChannels!=2) return;
1052 FChannels=AChannels;
1053 FAvgBytesPerSec=FSamplesPerSec*FBitsPerSample*FChannels/8;
1054 FBlockAlign=FBitsPerSample*FChannels/8;
1055 }
1056
1057 //---------------------------------------------------------------------------
1058 void __fastcall TWaveAudio::SetLVolume(unsigned __int16 ALVolume)
1059 {
1060 if (ALVolume!=FLVolume)
1061 {
1062 FLVolume=ALVolume;
1063 if (FPlaying) SetVolume();
1064 }
1065 }
1066
1067 //---------------------------------------------------------------------------
1068 void __fastcall TWaveAudio::SetRVolume(unsigned __int16 ARVolume)
1069 {
1070 if (ARVolume!=FRVolume)
1071 {
1072 FRVolume=ARVolume;
1073 if (FPlaying) SetVolume();
1074 }
1075 }
1076
1077 //---------------------------------------------------------------------------
1078 void __fastcall TWaveAudio::SetSamplesPerSec(__int32 ASamplesPerSec)
1079 {
1080 FSamplesPerSec=ASamplesPerSec;
1081 FAvgBytesPerSec=FSamplesPerSec*FBitsPerSample*FChannels/8;
1082 }
1083
1084 //---------------------------------------------------------------------------
1085 void __fastcall TWaveAudio::SetStreamLimit(int AStreamLimit)
1086 {
1087 if (AStreamLimit>0 && Stream->Size>AStreamLimit)
1088 {
1089 if (OnStreamLimitFailure) OnStreamLimitFailure(this);
1090 return;
1091 }
1092 FStreamLimit=AStreamLimit;
1093 }
1094
1095 void __fastcall TWaveAudio::SetUseMemoryStream(bool AUseMemoryStream)
1096 {
1097 if (FUseMemoryStream!=AUseMemoryStream)
1098 {
1099 FUseMemoryStream=AUseMemoryStream;
1100 }
1101 }
1102
1103 //---------------------------------------------------------------------------
1104 MMRESULT __fastcall TWaveAudio::SetVolume(void)
1105 {
1106 unsigned __int32 Volume=FRVolume;
1107 Volume=Volume<<16;
1108 Volume+=FLVolume;
1109 return waveOutSetVolume(WaveOut, Volume);
1110 }
1111
1112 //---------------------------------------------------------------------------
1113 void __fastcall TWaveAudio::StartPlayback(TObject* Sender)
1114 {
1115 if (FPlaying) return;
1116
1117 WAVEFORMATEX wfx;
1118 wfx.wFormatTag=FFormatTag;
1119 wfx.nChannels=FChannels;
1120 wfx.nSamplesPerSec=FSamplesPerSec;
1121 wfx.nAvgBytesPerSec=FAvgBytesPerSec;
1122 wfx.nBlockAlign=FBlockAlign;
1123 wfx.wBitsPerSample=FBitsPerSample;
1124 wfx.cbSize=FcbSize;
1125
1126 if (waveOutOpen(&WaveOut,WAVE_MAPPER,&wfx,(DWORD)HWndOut, NULL,
1127 CALLBACK_WINDOW)!=MMSYSERR_NOERROR)
1128 {
1129 throw EWriteError("TWaveAudio Err: Failed opening device WaveOut");
1130 }
1131
1132 SetVolume();
1133
1134 Buffer1=new char[FBlockSize];
1135 Buffer2=new char[FBlockSize];
1136 WaveHdr1=new WAVEHDR;
1137 WaveHdr2=new WAVEHDR;
1138
1139 WaveHdr1->lpData=(char*)Buffer1;
1140 WaveHdr1->dwBufferLength=FBlockSize;
1141 WaveHdr1->dwBytesRecorded=0;
1142 WaveHdr1->dwUser=0;
1143 WaveHdr1->dwFlags=0;
1144 WaveHdr1->dwLoops=1;
1145 WaveHdr1->lpNext=NULL;
1146 WaveHdr1->reserved=0;
1147
1148 WaveHdr2->lpData=(char*)Buffer2;
1149 WaveHdr2->dwBufferLength=FBlockSize;
1150 WaveHdr2->dwBytesRecorded=0;
1151 WaveHdr2->dwUser=0;
1152 WaveHdr2->dwFlags=0;
1153 WaveHdr2->dwLoops=1;
1154 WaveHdr2->lpNext=NULL;
1155 WaveHdr2->reserved=0;
1156
1157 int rc;
1158
1159 ResetOut=false;
1160 ResetOutUser=false;
1161
1162 rc=(FillBlock(WaveHdr1->lpData));
1163 if (rc!=FBlockSize)
1164 {
1165 if (BitsPerSample==8) memset(&WaveHdr1->lpData[rc],0x80,FBlockSize-rc);
1166 else memset(&WaveHdr1->lpData[rc],0,FBlockSize-rc);
1167 WaveHdr1->dwBufferLength=rc;
1168 ResetOut=true;
1169 }
1170 waveOutPrepareHeader(WaveOut,WaveHdr1,sizeof(WAVEHDR));
1171 waveOutWrite(WaveOut,WaveHdr1,sizeof(WAVEHDR));
1172
1173 if (FOnPlaybackProgress)
1174 FOnPlaybackProgress(this, 0);
1175 if (FOnPlaybackProg)
1176 FOnPlaybackProg(this, 0);
1177
1178 if (rc==BlockSize)
1179 {
1180 rc=(FillBlock(WaveHdr2->lpData));
1181 if (rc!=FBlockSize)
1182 {
1183 if (BitsPerSample==8) memset(&WaveHdr2->lpData[rc],0x80,FBlockSize-rc);
1184 else memset(&WaveHdr2->lpData[rc],0,FBlockSize-rc);
1185 WaveHdr2->dwBufferLength=rc;
1186 ResetOut=true;
1187 }
1188
1189 waveOutPrepareHeader(WaveOut,WaveHdr2,sizeof(WAVEHDR));
1190 waveOutWrite(WaveOut,WaveHdr2,sizeof(WAVEHDR));
1191
1192 if (FOnPlaybackProgress)
1193 FOnPlaybackProgress(this, (Stream->Position-FBlockSize)*1.0/Stream->Size);
1194 if (FOnPlaybackProg)
1195 FOnPlaybackProg(this, Stream->Position-FBlockSize);
1196
1197 }
1198 FPlaying=true;
1199 if (FOnStartPlayback) FOnStartPlayback(this);
1200 }
1201
1202 //---------------------------------------------------------------------------
1203 void __fastcall TWaveAudio::StartRecording(TObject* Sender)
1204 {
1205 if (FRecording) return;
1206
1207 WAVEFORMATEX wfx;
1208 wfx.wFormatTag=FFormatTag;
1209 wfx.nChannels=FChannels;
1210 wfx.nSamplesPerSec=FSamplesPerSec;
1211 wfx.nAvgBytesPerSec=FAvgBytesPerSec;
1212 wfx.nBlockAlign=FBlockAlign;
1213 wfx.wBitsPerSample=FBitsPerSample;
1214 wfx.cbSize=FcbSize;
1215
1216 MMRESULT tr=waveInOpen(&WaveIn, WAVE_MAPPER, &wfx, (unsigned long)HWndIn, NULL,
1217 CALLBACK_WINDOW);
1218 if (tr!=MMSYSERR_NOERROR && tr!=MMSYSERR_ALLOCATED)
1219 {
1220 throw EReadError("TWaveAudio err: Failed opening device WaveIn");
1221 }
1222
1223 Buffer1=new char[FBlockSize];
1224 Buffer2=new char[FBlockSize];
1225 WaveHdr1=new WAVEHDR;
1226 WaveHdr2=new WAVEHDR;
1227
1228 WaveHdr1->lpData=(char*)Buffer1;
1229 WaveHdr1->dwBufferLength=FBlockSize;
1230 WaveHdr1->dwBytesRecorded=0;
1231 WaveHdr1->dwUser=0;
1232 WaveHdr1->dwFlags=0;
1233 WaveHdr1->dwLoops=1;
1234 WaveHdr1->lpNext=NULL;
1235 WaveHdr1->reserved=0;
1236
1237 waveInPrepareHeader(WaveIn,WaveHdr1,sizeof(WAVEHDR));
1238
1239 WaveHdr2->lpData=(char*)Buffer2;
1240 WaveHdr2->dwBufferLength=FBlockSize;
1241 WaveHdr2->dwBytesRecorded=0;
1242 WaveHdr2->dwUser=0;
1243 WaveHdr2->dwFlags=0;
1244 WaveHdr2->dwLoops=1;
1245 WaveHdr2->lpNext=NULL;
1246 WaveHdr2->reserved=0;
1247
1248 waveInPrepareHeader(WaveIn,WaveHdr2,sizeof(WAVEHDR));
1249
1250 waveInAddBuffer(WaveIn,WaveHdr1,sizeof(WAVEHDR));
1251 waveInAddBuffer(WaveIn,WaveHdr2,sizeof(WAVEHDR));
1252
1253 ResetInStream=false;
1254 ResetInUser=false;
1255 FRecording=true;
1256
1257 waveInStart(WaveIn);
1258
1259 if (FOnStartRecording) FOnStartRecording(this);
1260 }
1261
1262 //---------------------------------------------------------------------------
1263 __fastcall TWaveAudio::TWaveAudio(TComponent* Owner)
1264 : TComponent(Owner)
1265 {
1266 FBlockSize=12288;
1267 FStreamLimit=0;
1268 FUseMemoryStream=true;
1269 FAutoUseMemoryStream=true;
1270 FMemoryStream=new TMemoryStream;
1271 FFileStream=new TAttachFileStream(NULL);
1272
1273 FPlaying=false;
1274 FRecording=false;
1275 FPaused=false;
1276
1277 FOnAudioChange=0;
1278 FOnStartPlayback=0;
1279 FOnStartRecording=0;
1280 FOnPlaybackDone=0;
1281 FOnRecordingDone=0;
1282 FOnStreamLimitFailure=0;
1283 FOnStreamFull=0;
1284 FOnPlaybackProgress=0;
1285 FOnPlaybackProg=0;
1286 FOnInAddBuffer=0;
1287 FOnOutWrite=0;
1288
1289 FSamplesPerSec=44100;
1290 FBitsPerSample=16;
1291 FChannels=1;
1292 FFileName="";
1293
1294 FFormatTag=WAVE_FORMAT_PCM;
1295 FcbSize=0; //ignored for PCM
1296 FAvgBytesPerSec=FSamplesPerSec*FBitsPerSample*FChannels/8;
1297 FBlockAlign=FBitsPerSample*FChannels/8;
1298
1299 HWndOut=AllocateHWnd(WaveOutProc);
1300 HWndIn=AllocateHWnd(WaveInProc);
1301
1302 unsigned long Volume;
1303 waveOutGetVolume((void *)WAVE_MAPPER, &Volume);
1304 FLVolume=Volume&0x0000FFFF;
1305 FRVolume=Volume>>16;
1306 }
1307
1308
1309 //---------------------------------------------------------------------------
1310 void __fastcall TWaveAudio::WaveInProc(TMessage& Message)
1311 {
1312 switch(Message.Msg)
1313 {
1314 case MM_WIM_OPEN: OnWimOpen(Message); break;
1315 case MM_WIM_DATA: OnWimData(Message); break;
1316 case MM_WIM_CLOSE: OnWimClose(Message); break;
1317 }
1318 }
1319
1320 //---------------------------------------------------------------------------
1321 void __fastcall TWaveAudio::WaveOutProc(TMessage& Message)
1322 {
1323 switch(Message.Msg)
1324 {
1325 case MM_WOM_OPEN: OnWomOpen(Message); break;
1326 case MM_WOM_DONE: OnWomDone(Message); break;
1327 case MM_WOM_CLOSE: OnWomClose(Message); break;
1328 }
1329 }
1330
1331 //---------------------------------------------------------------------------
1332 int __fastcall TWaveAudio::Write(void* Buffer, int Count)
1333 {
1334 if (!FUseMemoryStream)
1335 {
1336 int Position=FFileStream->Position;
1337 delete FFileStream->File;
1338 FFileStream->File=new TFileStream(FFileName, fmOpenWrite);
1339 FFileStream->Position=Position;
1340 }
1341 int result=Stream->Write(Buffer, Count);
1342 if (!FUseMemoryStream)
1343 {
1344 int Position=FFileStream->Position;
1345 delete FFileStream->File;
1346 FFileStream->File=new TFileStream(FFileName, fmOpenRead);
1347 FFileStream->Position=Position;
1348 }
1349 if (FOnAudioChange) FOnAudioChange(this);
1350 return result;
1351 }
1352
1353 int __fastcall TWaveAudio::WriteSamples(void* Buffer, int Count)
1354 {
1355 if (!FUseMemoryStream)
1356 {
1357 int Position=FFileStream->Position;
1358 delete FFileStream->File;
1359 FFileStream->File=new TFileStream(FFileName, fmOpenWrite);
1360 FFileStream->Position=Position;
1361 }
1362 int result=Stream->Write(Buffer, Count*FChannels*FBitsPerSample/8);
1363 if (!FUseMemoryStream)
1364 {
1365 int Position=FFileStream->Position;
1366 delete FFileStream->File;
1367 FFileStream->File=new TFileStream(FFileName, fmOpenRead);
1368 FFileStream->Position=Position;
1369 }
1370 if (FOnAudioChange) FOnAudioChange(this);
1371 return result;
1372 }
1373
1374 int __fastcall TWaveAudio::WriteSamples(double* Buffer, int Count)
1375 {
1376 int result=0;
1377 if (!FUseMemoryStream)
1378 {
1379 int Position=FFileStream->Position;
1380 delete FFileStream->File;
1381 FFileStream->File=new TFileStream(FFileName, fmOpenWrite);
1382 FFileStream->Position=Position;
1383 }
1384
1385 int FBytesPerSample=FBitsPerSample/8;
1386 if (FUseMemoryStream)
1387 {
1388 int Position=FMemoryStream->Position;
1389 result=Count*FBytesPerSample;
1390 if (FMemoryStream->Size<Position+result) FMemoryStream->Size=Position+result;
1391 DoubleToInt(&((char*)FMemoryStream->Memory)[Position], FBytesPerSample, Buffer, Count);
1392 FMemoryStream->Position=Position+result;
1393 }
1394 else
1395 {
1396 void *data=new char[FBlockSize];
1397 double *Data=Buffer;
1398 int CountPF=FBlockSize/FBytesPerSample;
1399 int Fr=(Count/CountPF);
1400 for (int i=0; i<Fr; i++)
1401 {
1402 DoubleToInt(data, FBytesPerSample, Data, CountPF);
1403 result+=Stream->Write(data, FBlockSize);
1404 Data=&Data[CountPF];
1405 }
1406 int CountLastF=Count%CountPF;
1407 int lastblocksize=CountLastF*FBytesPerSample;
1408 DoubleToInt(data, FBytesPerSample, Data, CountLastF);
1409 result+=Stream->Write(data, lastblocksize);
1410 delete[] data;
1411 }
1412
1413 if (!FUseMemoryStream)
1414 {
1415 int Position=FFileStream->Position;
1416 delete FFileStream->File;
1417 FFileStream->File=new TFileStream(FFileName, fmOpenRead);
1418 FFileStream->Position=Position;
1419 }
1420 if (FOnAudioChange) FOnAudioChange(this);
1421 return result;
1422 }
1423
1424 int __fastcall TWaveAudio::WriteSamplesInterleave(void* Buffer1, void* Buffer2, int Count)
1425 {
1426 int FBytesPerSample=FBitsPerSample/8;
1427 int SampleSize=FBytesPerSample*2;
1428 if (FUseMemoryStream)
1429 {
1430 int Position=FMemoryStream->Position;
1431 int countavailable=(FMemoryStream->Size-Position)/SampleSize;
1432 if (countavailable<Count) FMemoryStream->Size=Position+SampleSize*Count;
1433 IntToIntInterleave(&((char*)FMemoryStream->Memory)[Position], FBytesPerSample, Buffer1, Buffer2, Count);
1434 FMemoryStream->Position=Position+SampleSize*Count;
1435 }
1436 else
1437 {
1438 int Position=Stream->Position;
1439 delete FFileStream->File;
1440 FFileStream->File=new TFileStream(FFileName, fmOpenWrite);
1441 FFileStream->Position=Position;
1442
1443 int CountPF=FBlockSize/SampleSize, HBlockSize=FBlockSize/2;
1444 int Fr=Count/CountPF;
1445 void *Data1=Buffer1, *Data2=Buffer2, *data=new char[FBlockSize];
1446 for (int i=0; i<Fr; i++)
1447 {
1448 IntToIntInterleave(data, FBytesPerSample, Data1, Data2, CountPF);
1449 Stream->Write(data, FBlockSize);
1450 Data1=&((char*)Data1)[HBlockSize], Data2=&((char*)Data2)[HBlockSize];
1451 }
1452 int CountLastF=Count%CountPF;
1453 int lastblocksize=CountLastF*SampleSize;
1454 IntToIntInterleave(data, FBytesPerSample, Data1, Data2, CountLastF);
1455 Stream->Write(data, lastblocksize);
1456
1457 Position=Stream->Position;
1458 delete FFileStream->File;
1459 FFileStream->File=new TFileStream(FFileName, fmOpenRead);
1460 FFileStream->Position=Position;
1461 }
1462 if (FOnAudioChange) FOnAudioChange(this);
1463 return Count*SampleSize;
1464 }
1465
1466 int __fastcall TWaveAudio::WriteSamplesInterleave(double* Buffer1, double* Buffer2, int Count)
1467 {
1468 int FBytesPerSample=FBitsPerSample/8;
1469 int SampleSize=FBytesPerSample*2;
1470 if (FUseMemoryStream)
1471 {
1472 int Position=FMemoryStream->Position;
1473 int countavailable=(FMemoryStream->Size-Position)/SampleSize;
1474 if (countavailable<Count) FMemoryStream->Size=Position+SampleSize*Count;
1475 DoubleToIntInterleave(&((char*)FMemoryStream->Memory)[Position], FBytesPerSample, Buffer1, Buffer2, Count);
1476 FMemoryStream->Position=Position+SampleSize*Count;
1477 }
1478 else
1479 {
1480 int Position=Stream->Position;
1481 delete FFileStream->File;
1482 FFileStream->File=new TFileStream(FFileName, fmOpenWrite);
1483 FFileStream->Position=Position;
1484
1485 int CountPF=FBlockSize/SampleSize;
1486 int Fr=Count/CountPF;
1487 double *Data1=Buffer1, *Data2=Buffer2;
1488 void *data=new char[FBlockSize];
1489 for (int i=0; i<Fr; i++)
1490 {
1491 DoubleToIntInterleave(data, FBytesPerSample, Data1, Data2, CountPF);
1492 Stream->Write(data, FBlockSize);
1493 Data1=&Data1[CountPF], Data2=&Data2[CountPF];
1494 }
1495 int CountLastF=Count%CountPF;
1496 int lastblocksize=CountLastF*SampleSize;
1497 DoubleToIntInterleave(data, FBytesPerSample, Data1, Data2, CountLastF);
1498 Stream->Write(data, lastblocksize);
1499
1500 Position=Stream->Position;
1501 delete FFileStream->File;
1502 FFileStream->File=new TFileStream(FFileName, fmOpenRead);
1503 FFileStream->Position=Position;
1504 }
1505 if (FOnAudioChange) FOnAudioChange(this);
1506 return Count*SampleSize;
1507 }
1508 //---------------------------------------------------------------------------
1509 __fastcall TDataAudio::TDataAudio(TComponent* Owner)
1510 : TWaveAudio(Owner)
1511 {
1512 FCustomFillBlock=0;
1513 }
1514
1515 int __fastcall TDataAudio::FillBlock(void* Block)
1516 {
1517 if (FCustomFillBlock)
1518 return FCustomFillBlock(Block);
1519 else
1520 return TWaveAudio::FillBlock(Block);
1521 }
1522
1523 //---------------------------------------------------------------------------
1524 namespace Audiopac
1525 {
1526 void __fastcall PACKAGE Register()
1527 {
1528 TComponentClass classes[1] = {__classid(TWaveAudio)};
1529 RegisterComponents("Samples", classes, 0);
1530 }
1531 }
1532 //---------------------------------------------------------------------------
1533
1534