Реклама - двигатель сами понимаете чего
::Главная ->Форум

Форум

[Своя Книга]   [Сайт для программистов в среде Borland C++ Builder]
Добавить запись   Читать с начала  

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

    Rambler

    Яндекс цитирования

    ::Главная ->Форум
    Реклама - двигатель сами понимаете чего...
    (c) 2000 by AlmigoR
    Сайт управляется системой uCoz