xue@0: /* xue@0: Harmonic Visualiser xue@0: xue@0: An audio file viewer and editor. xue@0: Centre for Digital Music, Queen Mary, University of London. xue@0: This file copyright 2011 Wen Xue. xue@0: xue@0: This program is free software; you can redistribute it and/or xue@0: modify it under the terms of the GNU General Public License as xue@0: published by the Free Software Foundation; either version 2 of the xue@0: License, or (at your option) any later version. xue@0: */ xue@0: //--------------------------------------------------------------------------- xue@0: #ifndef AudioPacH xue@0: #define AudioPacH xue@0: //--------------------------------------------------------------------------- xue@0: /* xue@0: xue@0: AudioPac.cpp implements a VCL component for linear PCM waveform audio operations on xue@0: Windows using Win32 WAVEMAPPER device. xue@0: xue@0: Component class TWaveAudio xue@0: TWaveAudio is a VCL component that incapsulates the basic waveform audio i/o functions. xue@0: xue@0: Properties xue@0: xue@0: readwrite AutoUseMemoryStream xue@0: readonly AvgBytesPerSec xue@0: readwrite BitsPerSample xue@0: readonly BlockAlign xue@0: readwrite BlockSize xue@0: readonly BytesPerSample xue@0: readonly cbSize xue@0: readwrite Channels xue@0: readonly FileName xue@0: readonly FormatTag xue@0: readonly Length xue@0: readwrite LVolume xue@0: readonly Paused xue@0: readonly Playing xue@0: readonly Recording xue@0: readwrite RVolume xue@0: readwrite SamplesPerSec xue@0: readwrite StreamLimit xue@0: readwrite UseMemoryStream xue@0: readonly WaveStream xue@0: xue@0: xue@0: AutoUseMemoryStream xue@0: If set, the component automatically set UseMemoryStream to false when calling xue@0: LoadFromFile(...). xue@0: xue@0: AvgBytesPerSec xue@0: Standard waveform format property. xue@0: xue@0: BitsPerSample xue@0: Standard waveform format property. Usually 8, 16 or 24. xue@0: xue@0: BlockAlign xue@0: Standard waveform property. Gives the size of a multi-channels sample. xue@0: xue@0: BlockSize xue@0: Standard waveform format property. Specifies the size, in bytes, of the data xue@0: block used for audio recording and playback. In AudioPac42.cpp a total of xue@0: two data blocks are used. xue@0: xue@0: BytesPerSample xue@0: Equals BitsPerSample/8. xue@0: xue@0: cbSize xue@0: Standard waveform format property. Reserved. xue@0: xue@0: Channels xue@0: Standard waveform format property. Specifies the number of channels. xue@0: xue@0: FileName xue@0: The name of the file last loaded or inserted into this waveform. xue@0: xue@0: FormatTag xue@0: Standard waveform format property. Must be WAVE_FORMAT_PCM. xue@0: xue@0: Length xue@0: The length of waveform data held, in multi-channel samples. xue@0: xue@0: LVolume xue@0: Specifies the playback volume of left channel. xue@0: xue@0: Paused xue@0: Gives whether the playback is being suspended in pause mode. xue@0: xue@0: Playing xue@0: Gives whether the playback is in progress, whether or not suspended in pause xue@0: mode. xue@0: xue@0: Recording xue@0: Gives whether the recording is in progress. xue@0: xue@0: RVolume xue@0: Specifies the playback volume of right channel. xue@0: xue@0: SamplesPerSec xue@0: Standard waveform format property. As is. xue@0: xue@0: StreamLimit xue@0: This property provides a way to control the size of wave stream. If StreamLimit>0, xue@0: TWaveAudio will generate an StreamFull event when the size of wave stream xue@0: goes above StreamLimit. StreamLimit is set to zero by default. xue@0: xue@0: UseMemoryStream xue@0: Specifies whether the component loads the data samples into a memory stream. xue@0: If UseMemoryStream is set, a MemoryStream object is used to store the data xue@0: samples in the memroy. If UseMemoryStream is set to false, the WaveAudio must xue@0: be working on a wave file, where data samples are read from. Recording is xue@0: not allowed when UseMemoryStream is false. xue@0: xue@0: WaveStream xue@0: The pointer to the Stream object that holds the data samples. If UseMemoryStream xue@0: is true, the stream is a MemoryStream. If false, the stream is an AttachFileStream, xue@0: which is based on a FileStream. The data samples are stored right from the xue@0: beginning of WaveStream. xue@0: xue@0: xue@0: Methods: xue@0: xue@0: TWaveAudio & ~TWaveAudio xue@0: Default constructor and destructor. xue@0: xue@0: void Clear(); xue@0: void CloseFile(bool Close); xue@0: void CopyFrom(TStream* AStream, int Count); xue@0: void CopyFrom(TWaveAudio* AWaveAudio, int Count); xue@0: void CopySamplesFrom(TStream* AStream, int Count); xue@0: void CopySamplesFrom(TWaveAudio* AWaveAudio, int Count); xue@0: void CreateFile(AnsiString FileName); xue@0: void GetWaveProperties(TWaveAudio* WaveAudio1); xue@0: void InsertFromFile(AnsiString FileName); xue@0: bool IsValidWave(AnsiString FileName); xue@0: void LoadFromFile(AnsiString FileName); xue@0: void Pause(); xue@0: void PausePlayback(); xue@0: void PauseRecording(); xue@0: void Play(); xue@0: void Play(TNotifyEvent AnOnPlaybackDone); xue@0: int Read(void* Buffer, int Count); xue@0: bool ReadHeader(TStream* AStream, __int32& length, bool allowunfinisheddata); xue@0: int ReadSamples(void* Buffer, int Count); xue@0: int ReadSamples(double* Buffer, int Count); xue@0: int ReadSamplesMultiChannel(int C, void** Buffer, int Count); xue@0: int ReadSamplesMultiSingle(void* Buffer, int Channel, int Count); xue@0: int ReadSamplesInterleave(void* Buffer1, void* Buffer2, int Count); xue@0: void Restart(); xue@0: void Rewind(); xue@0: void SaveHeader(TStream* AStream); xue@0: void SaveToFile(AnsiString FileName); xue@0: void Seek(int Offset, WORD Origin); xue@0: void SeekSamples(int Offset, WORD Origin); xue@0: void StartPlayback(); xue@0: void StartRecording(); xue@0: int Write(void* Buffer, int Count); xue@0: int WriteSamples(void* Buffer, int Count); xue@0: int WriteSamples(double* Buffer, int Count); xue@0: int WriteSamplesInterleave(void* Buffer1, void* Buffer2, int Count); xue@0: int WriteSamplesInterleave(double* Buffer1, double* Buffer2, int Count); xue@0: xue@0: Clear() xue@0: Clear the stored sound in the stream. Be cautious using Clear() when UseMemoryStream xue@0: is true. xue@0: xue@0: CloseFile(bool Close) xue@0: Effective only if UseMemoryStream is false. A call to this method flushes the xue@0: audio content to the current working FileStream, closes the file handle of, xue@0: and reopens the audio file as a new FileStream if Close is false. xue@0: xue@0: CopyFrom(TStream* AStream, int Count) xue@0: The same as WaveStream->CopyFrom(AStream, Count) xue@0: xue@0: CopyFrom(TWaveAudio* AWaveAudio, int Count) xue@0: The same as WaveStream->CopyFrom(AWaveAudio->WaveStream, Count) xue@0: xue@0: CopySamplesFrom(TStream* AStream, int Count) xue@0: Similar to CopyFrom(AStream, Count), yet Count indicates the number of multi-channel xue@0: samples to be copied, not bytes. xue@0: xue@0: CopySamplesFrom(TWaveAudio* AWaveAudio, int Count) xue@0: Similar to CopyFrom(AWaveAudio, Count), yet Count indicates the numbet of xue@0: multi-channel samples to be copied, not bytes. xue@0: xue@0: CreateFile(AnsiString FileName) xue@0: Creates a new empty audio file as the current working audio stream. xue@0: xue@0: GetWaveProperties(TWaveAudio* WaveAudio1) xue@0: Fill the standard waveform audio properties with those of WaveAudio1. xue@0: xue@0: InsertFromFile(AnsiString FileName) xue@0: Loads in a wave file while giving up the previous content. It also sets the xue@0: FileName property. xue@0: xue@0: IsValidWave(AnsiString FileName) xue@0: Judge if a file specified with FileName is an valid waveform audio file. xue@0: xue@0: LoadFromFile(AnsiString FileName) xue@0: Almost the same as InsertFromFile(...) but triggers the OnBeforeLoad and OnLoad events xue@0: as well. xue@0: xue@0: Pause() xue@0: Suspends on-going playback in pause mode. It sets Paused property. xue@0: xue@0: PausePlayback() xue@0: Terminate playback. It also resets the Playing property and triggers an OnPlaybackDone xue@0: event. xue@0: xue@0: PauseRecording() xue@0: Terminate recording. It also resets the Recording property. xue@0: xue@0: Play() xue@0: Rewind() then StartPlayback(). xue@0: xue@0: Play(TNotifyEvent AnOnPlaybackDone) xue@0: Rewind() then StartPlayback() with AnOnPlaybackDone assigned to OnPlaybackDone xue@0: event. It is recommended that OnPlaybackDone be assigned at designtime rather xue@0: than at runtime. xue@0: xue@0: Read(void* Buffer, int Count) xue@0: The same as WaveStream->Read(Buffer, Count). xue@0: xue@0: ReadHeader(TStream* AStream, __int32& length, bool allowunfinisheddata) xue@0: Reads RIFF waveform header from AStream. xue@0: xue@0: ReadSamples(void* Buffer, int Count) xue@0: ReadSamples(double* Buffer, int Count); xue@0: Similar to Read(...), but Count is given in multi-channel samples, not in bytes. xue@0: xue@0: ReadSamplesInterleave(void* Buffer1, void* Buffer2, int Count) xue@0: ReadSamplesInterleave(double* Buffer1, double* Buffer2, int Count) xue@0: Reads interleaved stereo data into two data buffers. xue@0: xue@0: ReadSamplesMultiChannel(int C, void** Buffer, int Count) xue@0: Reads multi-channel audio stream into multiple buffers, one for each channel. xue@0: xue@0: ReadSamplesMultiSingle(void* Buffer, int Channel, int Count) xue@0: Reads the data of one channel from a multi-channel WaveAudio into a data buffer. xue@0: xue@0: Restart() xue@0: Resumes playback suspended in pause mode. It resets Paused property as well. xue@0: xue@0: Rewind() xue@0: Set the position of Stream to the beginning. xue@0: xue@0: SaveHeader(TStream* AStream) xue@0: Saves RIFF waveform header to AStream. xue@0: xue@0: SaveToFile(AnsiString FileName) xue@0: Saves current waveform stream to disk as a wave file. xue@0: xue@0: Seek(int Offset, WORD Origin) xue@0: The same as WaveStream->Seek(Offset, Origin). xue@0: xue@0: SeekSamples(int Offset, WORD Origin) xue@0: Similar to Seek(Offset, Origin), yet Offset is of the number of multi-channel samples, xue@0: not bytes. xue@0: xue@0: StartPlayback() xue@0: Start playback, starting from the current position of wave stream. It sets xue@0: Playing property. When playback is done, a PlaybackDone event is triggered xue@0: Playing is reset. xue@0: xue@0: StartRecording() xue@0: Start recording. New data will be written to stream from the current position. xue@0: Old data, if any, are overwritten. It sets the property Recording. Be cautious xue@0: using StartRecording() when UseMemoryStream is true. xue@0: xue@0: Write(void* Buffer, int Count) xue@0: The same as WaveStream->Write(Buffer, Count). Be cautious using Write(...) xue@0: when UseMemoryStream is false as in this case the audio file is overwritten. xue@0: xue@0: WriteSamples(void* Buffer, int Count) xue@0: WriteSamples(double* Buffer, int Count) xue@0: Similar to Write(...), but Count is given in multi-channel samples, not in xue@0: bytes. By cautious using WriteSamples when UseMemoryStream is false as in xue@0: this case the audio file is overwritten. xue@0: xue@0: WriteSamplesInterleave(void* Buffer1, void* Buffer2, int Count) xue@0: WriteSamplesInterleave(double* Buffer1, double* Buffer2, int Count) xue@0: Writes stereo data in two data buffers into the interleaved format of WaveAudio. xue@0: Be cautious using WriteSamplesInterleave when UseMemoryStream is false as xue@0: in this case the audio file is overwritten. xue@0: xue@0: xue@0: Events: xue@0: xue@0: OnAudioChange xue@0: OnBeforeLoad xue@0: OnInAddBuffer xue@0: OnLoad xue@0: OnOutWrite xue@0: OnPlaybackDone xue@0: OnPlaybackProg xue@0: OnPlaybackProgress xue@0: OnRecordingDone xue@0: OnStartPlayback xue@0: OnStartRecording xue@0: OnStreamFull xue@0: OnStreamLimitFailure xue@0: xue@0: xue@0: OnAudioChange xue@0: Triggered when the contents of the audio changes. This happens in the following cases: xue@0: 1. InsertFromFile method is called. xue@0: 2. A recording is finished. xue@0: 3. CopyFrom or CopySamplesFrom method is called. xue@0: 4. Clear method is called. xue@0: The change of audio content by calling methods of WaveAudio is not informed by this event. xue@0: xue@0: OnBeforeLoad xue@0: Triggered when a wave file is to be loaded. xue@0: xue@0: OnInAddBuffer xue@0: Triggered after a block received from the WaveIn device is released into local xue@0: data memory and the data block is returned to the WaveIn device. Handle this xue@0: event to access the latest received data in real time. xue@0: xue@0: OnLoad xue@0: Triggered when a wave file is loaded. xue@0: xue@0: OnOutWrite xue@0: Triggered when a data block has been sent to the WaveOut device. xue@0: xue@0: OnPlaybackDone xue@0: Triggered when playback is finished, whetherever PausePlayback method is called. xue@0: xue@0: OnPlaybackProg xue@0: OnPlaybackProgress xue@0: Triggered after each output data block is sent, and when playback is finished. xue@0: The two eveent differs in a progress parameter. While OnPlaybackProg uses an xue@0: integer parameter indicating the progress position in bytes, OnPlaybackProgress xue@0: uses a floating-point parameter indicating the progress position in percentage. xue@0: xue@0: OnRecordingDone xue@0: Triggered when recording is terminated and the WaveIn device is to be closed. xue@0: xue@0: OnStartPlayback xue@0: Triggered when playback is started. xue@0: xue@0: OnStartRecording xue@0: Triggered when recording is started. xue@0: xue@0: OnStreamFull xue@0: Triggered when the size of wave stream exceeds StreamLimit. No other operations xue@0: are done by TWaveForm. Application must handle this event to perform actual xue@0: size limit. xue@0: xue@0: OnStreamLimitFailure xue@0: Triggered when trying to set StreamLimit to a value smaller than the current xue@0: size of wave stream. TWaveAudio refuses this operation and generates the event. xue@0: xue@0: xue@0: Exceptions: xue@0: xue@0: "Failed opening device WaveIn" xue@0: Form: StartRecording xue@0: Thrown on failure of opening waveform audio input device. xue@0: xue@0: "Failed opening devece WaveOut" xue@0: From: StartPlayback xue@0: Thrown on failure of opening waveform audio output device. xue@0: xue@0: xue@0: Component class TDataAudio xue@0: TDataAudio is a decendent class of TWaveAudio, providing an CustomFillBlock event xue@0: to enable on-the-fly data calculation for playback. xue@0: xue@0: Events: xue@0: xue@0: CustomFillBlock xue@0: Triggered when a data block is to be filled by the application before sent to xue@0: WaveOut device. xue@0: xue@0: Current version Wen Xue 2009/7 xue@0: First version Wen Xue 2003/3 xue@0: */ xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: //#include xue@0: //#include xue@0: //#include xue@0: //#include xue@0: //#include xue@0: xue@0: #include xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: #ifndef INT24 xue@0: #define INT24 xue@0: struct __int24; xue@0: struct __pint24 xue@0: { xue@0: char* p; xue@0: __pint24(){} xue@0: __pint24(const void* ap){p=(char*)ap;} xue@0: __pint24& operator=(const void* ap){p=(char*)ap; return *this;} xue@0: __int24& operator*(){return *(__int24*)p;} xue@0: __int24& operator[](int index){return *(__int24*)&p[3*index];} xue@0: __pint24 operator++(int){__pint24 result=*this; p+=3; return result;} xue@0: __pint24& operator++(){p+=3; return *this;} xue@0: __pint24 operator--(int){__pint24 result=*this; p-=3; return result;} xue@0: __pint24& operator--(){p-=3; return *this;} xue@0: __pint24& operator+=(int a){p+=3*a; return *this;} xue@0: __pint24& operator-=(int a){p-=3*a; return *this;} xue@0: operator void*() const{return p;} xue@0: }; xue@0: struct __int24 xue@0: { xue@0: __int16 loword; xue@0: __int8 hibyte; xue@0: __int24(){} xue@0: __int24(const __int32 a){loword=*(__int16*)&a; hibyte=((__int16*)&a)[1];} xue@0: __int24(const double f){__int32 a=f; loword=*(__int16*)&a; hibyte=((__int16*)&a)[1];} xue@0: __int24& operator=(const __int32 a){loword=*(__int16*)&a; hibyte=((__int16*)&a)[1]; return *this;} xue@0: __int24& operator=(const double f){__int32 a=f; loword=*(__int16*)&a; hibyte=((__int16*)&a)[1]; return *this;} xue@0: __int24& operator+=(const __int32 a){__int32 b=*this; b+=a; loword=*(__int16*)&b; hibyte=((__int16*)&b)[1]; return *this;} xue@0: __int24& operator-=(const __int32 a){__int32 b=*this; b-=a; loword=*(__int16*)&b; hibyte=((__int16*)&b)[1]; return *this;} xue@0: __int24& operator*=(const __int32 a){__int32 b=*this; b*=a; loword=*(__int16*)&b; hibyte=((__int16*)&b)[1]; return *this;} xue@0: operator __int32() const{__int32 result; *(__int16*)&result=loword; ((__int16*)&result)[1]=hibyte; return result;} xue@0: __pint24 operator &(){return (__pint24)this;} xue@0: void* operator new[](size_t count){void* result=malloc(3*count); return result;} xue@0: void operator delete[](void* p){free(p);} xue@0: }; xue@0: #endif xue@0: xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: void DoubleToIntInterleave(void* _out, int BytesPerSample, double* in1, double* in2, int Count); xue@0: void IntToDoubleInterleave(double* out1, double* out2, void* _in, int BytesPerSample, int Count); xue@0: int IntToIntInterleave(void* dest, int bytesperunit, void* block1, void* block2, int Count); xue@0: int IntToIntInterleave(void* dest1, void* dest2, int bytesperunit, void* block, int Count); xue@0: int IntToIntMultiSingle(void* dest, int bytesperunit, int channels, int channel, void* block, int Count); xue@0: xue@0: typedef void __fastcall (__closure *TWaveAudioPlaybackProgressEvent)(System::TObject* Sender, double PlaybackPosition); xue@0: xue@0: class TAttachFileStream : public TStream xue@0: { xue@0: public: xue@0: TFileStream* File; xue@0: int StartOffset; xue@0: int EndOffset; xue@0: protected: xue@0: virtual int __fastcall Seek(int AnOffset, Word Origin); xue@0: virtual __int64 __fastcall Seek(const __int64 AnOffset, TSeekOrigin Origin); xue@0: virtual int __fastcall Read(void *Buffer, int Count); xue@0: virtual int __fastcall Write(const void *Buffer, int Count); xue@0: public: xue@0: __fastcall TAttachFileStream(TFileStream* AFileStream); xue@0: __fastcall ~TAttachFileStream(); xue@0: }; xue@0: xue@0: class TWaveView; xue@0: class PACKAGE TWaveAudio : public TComponent xue@0: { xue@0: friend TWaveView; xue@0: xue@0: protected: xue@0: xue@0: bool FUseMemoryStream; xue@0: TMemoryStream* FMemoryStream; xue@0: TAttachFileStream* FFileStream; xue@0: xue@0: AnsiString FFileName; xue@0: __int32 FSamplesPerSec; xue@0: __int16 FBitsPerSample; xue@0: __int16 FChannels; xue@0: __int32 FAvgBytesPerSec; xue@0: __int16 FBlockAlign; xue@0: __int16 FFormatTag; xue@0: __int16 FcbSize; xue@0: unsigned __int16 FLVolume; xue@0: unsigned __int16 FRVolume; xue@0: int FStreamLimit; xue@0: int FBlockSize; xue@0: xue@0: TNotifyEvent FOnBeforeLoad; xue@0: TNotifyEvent FOnAudioChange; xue@0: TNotifyEvent FOnInAddBuffer; xue@0: TNotifyEvent FOnLoad; xue@0: TNotifyEvent FOnOutWrite; xue@0: TNotifyEvent FOnPlaybackDone; xue@0: TNotifyEvent FOnRecordingDone; xue@0: TNotifyEvent FOnStartPlayback; xue@0: TNotifyEvent FOnStartRecording; xue@0: TNotifyEvent FOnStreamFull; xue@0: TNotifyEvent FOnStreamLimitFailure; xue@0: xue@0: TWaveAudioPlaybackProgressEvent FOnPlaybackProgress; xue@0: TWaveAudioPlaybackProgressEvent FOnPlaybackProg; xue@0: xue@0: bool FAutoUseMemoryStream; xue@0: bool FRecording; xue@0: bool FPlaying; xue@0: bool FPaused; xue@0: xue@0: __property TStream* Stream={read=GetStream}; xue@0: xue@0: public: xue@0: HWAVEIN WaveIn; xue@0: HWAVEOUT WaveOut; xue@0: xue@0: protected: xue@0: HWND HWndOut; xue@0: HWND HWndIn; xue@0: xue@0: WAVEHDR* WaveHdr1; xue@0: WAVEHDR* WaveHdr2; xue@0: void* Buffer1; xue@0: void* Buffer2; xue@0: bool ResetInStream; xue@0: bool ResetInUser; xue@0: bool ResetOut; xue@0: bool ResetOutUser; xue@0: xue@0: protected: xue@0: virtual void __fastcall SetSamplesPerSec(__int32 ASamplesPerSec); xue@0: virtual void __fastcall SetBitsPerSample(__int16 ABitsPerSample); xue@0: virtual void __fastcall SetChannels(__int16 AChannels); xue@0: virtual void __fastcall SetBlockSize(int ABlockSize); xue@0: virtual void __fastcall SetStreamLimit(int AStreamLimit); xue@0: virtual void __fastcall SetLVolume(unsigned __int16 ALVolume); xue@0: virtual void __fastcall SetRVolume(unsigned __int16 ARVolume); xue@0: virtual void __fastcall SetUseMemoryStream(bool AUseMemoryStream); xue@0: virtual int __fastcall FillBlock(void* Block); xue@0: virtual int __fastcall GetBytesPerSample(); xue@0: virtual __int32 __fastcall GetLength(); xue@0: virtual TStream* __fastcall GetStream(); xue@0: MMRESULT __fastcall SetVolume(void); xue@0: virtual void __fastcall ReleaseBlock(void* Block, int BytesRecorded); xue@0: xue@0: virtual void __fastcall OnWomOpen(TMessage& Message); xue@0: virtual void __fastcall OnWomDone(TMessage& Message); xue@0: virtual void __fastcall OnWomClose(TMessage& Message); xue@0: virtual void __fastcall OnWimOpen(TMessage& Message); xue@0: virtual void __fastcall OnWimData(TMessage& Message); xue@0: virtual void __fastcall OnWimClose(TMessage& Message); xue@0: void __fastcall WaveOutProc(TMessage& Message); xue@0: void __fastcall WaveInProc(TMessage& Message); xue@0: xue@0: public: xue@0: __property AnsiString FileName={read=FFileName}; xue@0: __property __int32 AvgBytesPerSec={read=FAvgBytesPerSec}; xue@0: __property __int16 BlockAlign={read=FBlockAlign}; xue@0: __property int BytesPerSample={read=GetBytesPerSample}; xue@0: __property __int16 FormatTag={read=FFormatTag}; xue@0: __property __int16 cbSize={read=FcbSize}; xue@0: __property __int32 Length={read=GetLength}; xue@0: xue@0: __property TStream* WaveStream={read=GetStream}; xue@0: __property bool Recording={read=FRecording}; xue@0: __property bool Playing={read=FPlaying}; xue@0: __property bool Paused={read=FPaused}; xue@0: xue@0: virtual __fastcall TWaveAudio(TComponent* Owner); xue@0: virtual __fastcall ~TWaveAudio(); xue@0: xue@0: void __fastcall Clear(TObject* Sender); xue@0: void __fastcall CloseFile(bool Close=true); xue@0: void CopyFrom(TStream* AStream, int Count); xue@0: void CopyFrom(TWaveAudio* AWaveAudio, int Count); xue@0: void CopySamplesFrom(TStream* AStream, int Count); xue@0: void CopySamplesFrom(TWaveAudio* AWaveAudio, int Count); xue@0: void CreateFile(AnsiString FileName); xue@0: void GetWaveProperties(TWaveAudio* WaveAudio1); xue@0: void InsertFromFile(AnsiString FileName); xue@0: bool IsValidWave(AnsiString FileName); xue@0: void LoadFromFile(AnsiString FileName); xue@0: void __fastcall OpenFile(AnsiString AFileName); xue@0: void __fastcall Pause(TObject* Sender); xue@0: void __fastcall PausePlayback(TObject* Sender); xue@0: void __fastcall PauseRecording(TObject* Sender); xue@0: void __fastcall Play(TObject* Sender); xue@0: void __fastcall Play(TNotifyEvent AnOnPlaybackDone); xue@0: int __fastcall Read(void* Buffer, int Count); xue@0: bool __fastcall ReadHeader(TStream* AStream, __int32& length, bool allowunfinisheddata=false); xue@0: int __fastcall ReadSamples(void* Buffer, int Count); xue@0: int __fastcall ReadSamples(double* Buffer, int Count); xue@0: int __fastcall ReadSamplesInterleave(void* Buffer1, void* Buffer2, int Count); xue@0: int __fastcall ReadSamplesInterleave(double* Buffer1, double* Buffer2, int Count); xue@0: int __fastcall ReadSamplesMultiChannel(int C, void** Buffer, int Count); xue@0: int __fastcall ReadSamplesMultiSingle(void* Buffer, int Channel, int Count); xue@0: void __fastcall Restart(TObject* Sender); xue@0: void __fastcall Rewind(TObject* Sender); xue@0: void __fastcall SaveHeader(TStream* AStream); xue@0: void __fastcall SaveToFile(AnsiString FileName); xue@0: void __fastcall Seek(int Offset, WORD Origin); xue@0: void __fastcall SeekSamples(int Offset, WORD Origin); xue@0: void __fastcall StartPlayback(TObject* Sender); xue@0: void __fastcall StartRecording(TObject* Sender); xue@0: int __fastcall Write(void* Buffer, int Count); xue@0: int __fastcall WriteSamples(void* Buffer, int Count); xue@0: int __fastcall WriteSamples(double* Buffer, int Count); xue@0: int __fastcall WriteSamplesInterleave(void* Buffer1, void* Buffer2, int Count); xue@0: int __fastcall WriteSamplesInterleave(double* Buffer1, double* Buffer2, int Count); xue@0: xue@0: __published: xue@0: __property bool AutoUseMemoryStream={read=FAutoUseMemoryStream, write=FAutoUseMemoryStream}; xue@0: __property __int16 BitsPerSample={read=FBitsPerSample,write=SetBitsPerSample,default=8}; xue@0: __property int BlockSize={read=FBlockSize,write=SetBlockSize,default=4096}; xue@0: __property __int16 Channels={read=FChannels,write=SetChannels,default=1}; xue@0: __property unsigned __int16 LVolume={read=FLVolume, write=SetLVolume, default=0xFFFF}; xue@0: __property unsigned __int16 RVolume={read=FRVolume, write=SetRVolume, default=0xFFFF}; xue@0: __property __int32 SamplesPerSec={read=FSamplesPerSec,write=SetSamplesPerSec,default=11025}; xue@0: __property int StreamLimit={read=FStreamLimit,write=SetStreamLimit,default=0}; xue@0: __property bool UseMemoryStream={read=FUseMemoryStream, write=SetUseMemoryStream}; xue@0: xue@0: __property TNotifyEvent OnAudioChange={read=FOnAudioChange,write=FOnAudioChange}; xue@0: __property TNotifyEvent OnBeforeLoad={read=FOnBeforeLoad, write=FOnBeforeLoad}; xue@0: __property TNotifyEvent OnInAddBuffer={read=FOnInAddBuffer, write=FOnInAddBuffer}; xue@0: __property TNotifyEvent OnLoad={read=FOnLoad, write=FOnLoad}; xue@0: __property TNotifyEvent OnOutWrite={read=FOnOutWrite, write=FOnOutWrite}; xue@0: __property TNotifyEvent OnPlaybackDone={read=FOnPlaybackDone,write=FOnPlaybackDone}; xue@0: __property TNotifyEvent OnRecordingDone={read=FOnRecordingDone,write=FOnRecordingDone}; xue@0: __property TNotifyEvent OnStartPlayback={read=FOnStartPlayback, write=FOnStartPlayback}; xue@0: __property TNotifyEvent OnStartRecording={read=FOnStartRecording, write=FOnStartRecording}; xue@0: __property TNotifyEvent OnStreamFull={read=FOnStreamFull,write=FOnStreamFull}; xue@0: __property TNotifyEvent OnStreamLimitFailure={read=FOnStreamLimitFailure,write=FOnStreamLimitFailure}; xue@0: __property TWaveAudioPlaybackProgressEvent OnPlaybackProgress={read=FOnPlaybackProgress, write=FOnPlaybackProgress}; xue@0: __property TWaveAudioPlaybackProgressEvent OnPlaybackProg={read=FOnPlaybackProg, write=FOnPlaybackProg}; xue@0: }; xue@0: xue@0: typedef int __fastcall (__closure *TDataAudioFillBlockEvent)(void* ABlock); xue@0: xue@0: class TDataAudio : public TWaveAudio xue@0: { xue@0: private: xue@0: TDataAudioFillBlockEvent FCustomFillBlock; xue@0: protected: xue@0: virtual int __fastcall FillBlock(void*); xue@0: public: xue@0: virtual __fastcall TDataAudio(TComponent* Owner); xue@0: __published: xue@0: __property TDataAudioFillBlockEvent CustomFillBlock={read=FCustomFillBlock, write=FCustomFillBlock}; xue@0: }; xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: #endif xue@0: