|
Форум
Victor: Пример работы с waveIn...
Привожу полный текст проверенной в работе программы. Проверка проводилась на машине с FM Radio, в качестве источника входных сигналов. Пример показывает использование функций waveIn... в поточном режиме и выводит уровень входных LineIn сигналов в ProgressBar'ы. В ComboBox1 выбор: 8000,11025,22050,44100. В RadioGroup1: Mono,Stereo. В RadioGroup2: 8 bits, 16 bits. Button1 - Запуск. Button2 - Остановка. Button3 - Exit. Label1 - "Left", Label2- "Right", Label3 -"Sound Opeb/Close". ProgressBar1 и 2 - Min=0,Max=100,Step=1,Smooth=true. //===================== //Unit1.h //--------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include #include #include #include #include #include #include //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; TProgressBar *ProgressBar1; TProgressBar *ProgressBar2; TLabel *Label1; TLabel *Label2; TButton *Button2; TButton *Button3; TComboBox *ComboBox1; TRadioGroup *RadioGroup1; TRadioGroup *RadioGroup2; TLabel *Label3; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); void __fastcall Button3Click(TObject *Sender); void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); private: // User declarations void __fastcall MyDoMessage(TMessage &msg); bool __fastcall OpenWaveIn(HWND hWnd,int nChan,int Freq,int Bits); void __fastcall CloseWaveIn(HWND hWnd); bool __fastcall DataWaveIn(HWND hWnd, HWAVEIN hwav, LPWAVEHDR pHdr); public: // User declarations __fastcall TForm1(TComponent* Owner); protected: BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_USER+1, TMessage, WMUSER1) VCL_MESSAGE_HANDLER(WM_USER+2, TMessage, WMUSER2) END_MESSAGE_MAP(TForm) void __fastcall WMUSER1(TMessage & msg); void __fastcall WMUSER2(TMessage & msg); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif //end Unit.h //===================== //Unit1.cpp //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int Freq=44100,nChan=2,nBits=8; //Default // ----- Для waveIn ---------- HWND MyhWnd=NULL; // buffers into which sound data is recorded #define NUM_LEVEL_BUFFERS 2 // the buffer size is calculated to be about 1/20 sec #define UPDATES_PER_SEC 20 LPWAVEFORMATEX pwfx=NULL; typedef struct tagLevelWaveIn { HWAVEIN hwav; LPWAVEFORMATEX pwfx; int buffersize; LPWAVEHDR alpWave[NUM_LEVEL_BUFFERS]; } LEVELWAVEIN, *PLEVELWAVEIN; // ----- Для waveIn ---------- //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { ComboBox1->ItemIndex=3; // 44100 Hz RadioGroup1->ItemIndex=1; //Stereo RadioGroup2->ItemIndex=0; //8 bits ProgressBar1->Position=0; ProgressBar2->Position=0; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { if(MyhWnd) { if(MyhWnd)DeallocateHWnd(MyhWnd); MyhWnd=NULL; } //Создаю окно для отработки сообщений waveIn MyhWnd=AllocateHWnd(MyDoMessage); if(!MyhWnd){ ShowMessage("No create MyhWnd"); return; } Freq=StrToInt(ComboBox1->Items->Strings[ComboBox1->ItemIndex]); nChan=RadioGroup1->ItemIndex+1; nBits=(RadioGroup2->ItemIndex+1)*8; // Запускаем waveIn if(!OpenWaveIn(MyhWnd,nChan,Freq,nBits)) { if(MyhWnd)DeallocateHWnd(MyhWnd); MyhWnd=NULL; ShowMessage("Err Open SoundDriver"); return; } Label3->Caption="Sound Open"; //И процесс пошёл } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { if(MyhWnd)DeallocateHWnd(MyhWnd); MyhWnd=NULL; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { if(MyhWnd)DeallocateHWnd(MyhWnd); MyhWnd=NULL; Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose) { if(MyhWnd)DeallocateHWnd(MyhWnd); MyhWnd=NULL; } //--------------------------------------------------------------------------- void __fastcall TForm1::MyDoMessage(TMessage &msg) { switch(msg.Msg) { case MM_WIM_OPEN: //Просто можно вывести в StatusBar текст break; case MM_WIM_DATA: if (!DataWaveIn(MyhWnd,(HWAVEIN)msg.WParam,(LPWAVEHDR)msg.LParam)){ ShowMessage("Err Access SoundDriver"); CloseWaveIn(MyhWnd); } break; case MM_WIM_CLOSE: //Просто можно вывести в StatusBar текст break; case WM_DESTROY: CloseWaveIn(MyhWnd); Label3->Caption="Sound Close"; default: msg.Result = DefWindowProc(MyhWnd, msg.Msg, msg.WParam, msg.LParam); } } //--------------------------------------------------------------------------- //open the wave-device in the given format, queue all the buffers and //start data streaming. Save the wavein device to the GWL_USERDATA window //data area so we can close it on window destroy. bool __fastcall TForm1::OpenWaveIn(HWND hWnd,int nChan,int Freq,int nBits) { PLEVELWAVEIN pInfo; int i; pInfo = new LEVELWAVEIN; if(!pInfo)return false; pwfx = new WAVEFORMATEX; if(!pwfx)return false; memset(pwfx,0,sizeof(WAVEFORMATEX)); // Значения которые можно задавать в диалоге pwfx->nChannels=nChan; //1(Mono) or 2(Stereo) pwfx->nSamplesPerSec=Freq; //8000,11025,22050,44100 pwfx->wBitsPerSample=nBits; //8 bit or 16 bit //Заполним поля структуры pwfx->wFormatTag = WAVE_FORMAT_PCM; pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8; pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; // save for later use pInfo->pwfx = pwfx; // buffer size a fixed fraction of a second pInfo->buffersize = pwfx->nAvgBytesPerSec/UPDATES_PER_SEC; pInfo->hwav = NULL; //Устанавливаем связь с драйвером if (waveInOpen( &pInfo->hwav, WAVE_MAPPER, pwfx, (DWORD) hWnd,// callback via MM_WIM_ messages to wndproc 0, CALLBACK_WINDOW)) { SetWindowLong(hWnd, GWL_USERDATA, 0); return(FALSE); } // store the info structure in the dialog, so that even if we fail // on this routine we will clean up correctly SetWindowLong(hWnd, GWL_USERDATA, (long)pInfo); // set all the wave headers to null (for cleanup if error) for(i = 0; i < NUM_LEVEL_BUFFERS; i++)pInfo->alpWave[i] = NULL; // alloc, prepare and add all the buffers for (i = 0; i < NUM_LEVEL_BUFFERS; i++) { pInfo->alpWave[i] =(LPWAVEHDR)new char[sizeof(WAVEHDR)+pInfo->buffersize]; if (pInfo->alpWave[i] == NULL)return false; pInfo->alpWave[i]->lpData = (LPBYTE) (pInfo->alpWave[i] + 1); pInfo->alpWave[i]->dwBufferLength = pInfo->buffersize; pInfo->alpWave[i]->dwBytesRecorded = 0; pInfo->alpWave[i]->dwUser = 0; pInfo->alpWave[i]->dwFlags = 0; pInfo->alpWave[i]->dwLoops = 0; if (waveInPrepareHeader(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR))) return false; if (waveInAddBuffer(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR))) return false; } waveInStart(pInfo->hwav); return true; } //--------------------------------------------------------------------------- // terminate the data streaming on a wavein device associated with a // window, and clean up the buffers allocated void __fastcall TForm1::CloseWaveIn(HWND hWnd) { PLEVELWAVEIN pInfo; int i; // pick up our info from the dialog pInfo = (PLEVELWAVEIN) GetWindowLong(hWnd, GWL_USERDATA); if ((pInfo == NULL) !! (pInfo->hwav == NULL))return; // stop streaming data waveInStop(pInfo->hwav); // release all buffers waveInReset(pInfo->hwav); // unlock and free buffers for (i = 0; i < NUM_LEVEL_BUFFERS; i++) { if (pInfo->alpWave[i]) { waveInUnprepareHeader(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR)); delete pInfo->alpWave[i]; pInfo->alpWave[i] = NULL; } } waveInClose(pInfo->hwav); delete pInfo; SetWindowLong(hWnd, GWL_USERDATA, 0); SendMessage(Form1->Handle,WM_USER+1, 0, 0); SendMessage(Form1->Handle,WM_USER+2, 0, 0); } //--------------------------------------------------------------------------- // we have received a block of data. work out the level(s) and send to // the appropriate control on the ProgressBar, and then requeue the buffer. // return FALSE if any error occurs, otherwise TRUE bool __fastcall TForm1::DataWaveIn(HWND hWnd, HWAVEIN hwav, LPWAVEHDR pHdr) { PLEVELWAVEIN pInfo; int n = 0; int LevelLeft = 0, LevelRight = 0; int i, l; // pick up our info from the dialog pInfo = (PLEVELWAVEIN) GetWindowLong(hWnd, GWL_USERDATA); if ((pInfo == NULL) !! (pInfo->hwav != hwav))return false; // go through all samples in buffer looking for maximum absolute level while (n < pInfo->buffersize) { /* * volumes go above and below the mean level - we are * interested in the absolute volume * 8 bit samples are in the range 0..255 * 16-bit samples are in the range -32768..+32767 */ // skip the first byte if 16-bit // and adjust to be in range -127..+128 if (pInfo->pwfx->wBitsPerSample == 16) { n++; i = (int) (signed char) pHdr->lpData[n]; } else i=(int) ((unsigned char) pHdr->lpData[n]) - 128; // skip past the byte we've picked up n++; // take absolute volume level if (i < 0)i = -i; // convert to percentage l = (i*100) / 128; // compare against current max if (LevelLeft < l)LevelLeft = l; // if stereo, repeat for right channel if (pInfo->pwfx->nChannels == 2) { // skip the first byte if 16-bit if (pInfo->pwfx->wBitsPerSample == 16) { n++; i = (int) (signed char) pHdr->lpData[n]; } else i=(int) ((unsigned char) pHdr->lpData[n]) - 128; // skip past the byte we've picked up n++; // take absolute volume level if (i < 0)i = -i; // convert to percentage l = (i*100) / 128; // compare against current max if (LevelRight < l)LevelRight = l; } //Правый канал, если стерео } // Пробежка по массиву данных // put the buffer back on the queue if (waveInAddBuffer(pInfo->hwav, pHdr, sizeof(WAVEHDR)))return false; // send new level to ProgressBar control SendMessage(Form1->Handle,WM_USER+1, 0, LevelLeft); if (pInfo->pwfx->nChannels == 2) SendMessage(Form1->Handle,WM_USER+2, 0, LevelRight); return(TRUE); } //--------------------------------------------------------------------------- void __fastcall TForm1::WMUSER1(TMessage &msg) { //TODO: Add your source code here ProgressBar1->Position=msg.LParam; } //--------------------------------------------------------------------------- void __fastcall TForm1::WMUSER2(TMessage &msg) { //TODO: Add your source code here ProgressBar2->Position=msg.LParam; } //--------------------------------------------------------------------------- // end Unit1.cpp
4 Августа 2000, 11:02:01
К списку
1442. Andrew
Захват звука с LineIn Авг 3, 14:04
Victor
re: Захват звука с LineIn Авг 3, 15:02
Andrew
Срасибо, Victor Авг 3, 15:45
Victor
А может слинковать эти примеры? Авг 3, 15:52
Andrew
re: А может слинковать эти примеры? Авг 3, 16:59
Victor
Отвечу как только напишу пример! Письмо же отправляю сейчас. (-) Авг 4, 06:48
Andrew
сенкс а лот Авг 4, 07:33
- Victor
Пример работы с waveIn... Авг 4, 11:02
Andrew
по поводу форматов Авг 4, 16:46
Victor
re: по поводу форматов Авг 4, 16:52
Andrew
re: по поводу 16 бит Авг 5, 13:42
Victor
re: по поводу 16 бит Авг 7, 06:13
Victor
Уточнение... Авг 7, 06:58
Andrew
abot volume Авг 7, 10:12
Victor
Влияет непосредственно.... Авг 7, 10:32
Михаил
Есть по этому поводу книга... Авг 7, 00:21
Andrew
re: Есть по этому поводу книга... Авг 7, 13:42
Victor
Ссылки от yandex... Авг 7, 14:49
Andrew
re: Ссылки от yandex... Авг 8, 07:32
Переход по нитям:
1443 <<< 1442 >>> 1441
710784912109
Статистика: нитей 3077, записей 10900
|
710784912109710784912109
|