annotate AudioPac.cpp @ 1:f3fd4e19cec0 tip

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