"Mark Jacobs" <ma...@losethisbitjacobsm.com> wrote in message
news:4069...@newsgroups.borland.com...
HTH Pete
"Mark Jacobs" <markjremovethisspu...@critical.co.uk> wrote in
message news:406a...@newsgroups.borland.com...
> I have looked, tried, tinkered and fretted. I do not know whether to open
waveIn or waveOut in order to
> monitor currently playing levels. I keep getting "An invalid flag was
passed to a system function." (code 10)
> from the following code :-
<snipped lots>
If I change the waveOutOpen line to read :-
wh=waveOutOpen(&phwo,0,&pwfx,0,0,WAVE_MAPPED);
I get both channels maxed out constantly, whether there is sound or not.
The timer is firing 10 times a second. I am floundering - please help.
--
Mark Jacobs
DK Computing
http://www.dkcomputing.co.uk
ma...@criticalremovethisspuriousantispamstuff.co.uk
"Pete Fraser" <pete._no_s...@frasersoft.nospam.net> wrote in message
news:406a...@newsgroups.borland.com...
> Yes there is. Look in the multimedia API help files under SDK help on
> Borland Start menu
"Pete Fraser" <pete._no_s...@frasersoft.nospam.net> wrote in message
news:406aa6a9$1...@newsgroups.borland.com...
"Pete Fraser" <pete._no_s...@frasersoft.nospam.net> wrote in message
news:406aa6a9$1...@newsgroups.borland.com...
// In the public section of your form, add the following :-
public: // User declarations
char erst[199];
unsigned char wvbfr[99];
HWAVEIN phwo;
WAVEFORMATEX pwfx;
MMRESULT wh;
WAVEHDR wvhd;
void __fastcall ProcessInput();
// then on the form's paint event put this :-
//--------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
static bool clld=false;
if (clld) return;
clld=true;
pwfx.cbSize=0;
pwfx.wFormatTag=WAVE_FORMAT_PCM;
pwfx.nChannels=2;
pwfx.nSamplesPerSec=44100;
pwfx.wBitsPerSample=16;
pwfx.nAvgBytesPerSec=44100*2*16/8;
pwfx.nBlockAlign=2*16/8;
wh=waveInOpen(&phwo,WAVE_MAPPER,&pwfx,(DWORD)WaveInProc,
(DWORD)this,CALLBACK_FUNCTION);
if (wh!=MMSYSERR_NOERROR)
{
waveOutGetErrorText(wh,erst,190);
Edit3->Text="Error="+AnsiString(erst);
zcMMTimer1->Enabled=false;
}
else zcMMTimer1->Enabled=true;
}
//--------------------------------------------------------------------------
// Somewhere in the form module declare the following callback functions :-
void CALLBACK WaveInProc(HWAVEIN waveIn,UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,DWORD dwParam2)
{
if (uMsg==MM_WIM_DATA) Form1->ProcessInput();
}
//--------------------------------------------------------------------------
void __fastcall TForm1::ProcessInput()
{
short *mybf=(short *)wvbfr;
waveInStop(phwo);
wh=waveInUnprepareHeader(phwo,&wvhd,sizeof(WAVEHDR));
if (wh!=MMSYSERR_NOERROR) return;
zcDinMeter1->Value=(int)mybf[0]*100*zSlideBar1->Value/32768;
zcDinMeter2->Value=(int)mybf[1]*100*zSlideBar1->Value/32768;
zcMMTimer1->Enabled=true;
}
//--------------------------------------------------------------------------
/*
Add a timer to the form. It should be set to an interval of 50ms or less to
be useful, but 100ms seems to be adequate. I use Ziegler's Multimedia Timer
so I can get good results from 20ms resolution. In the timer's OnTimer
event, put the following :-
*/
//--------------------------------------------------------------------------
void __fastcall TForm1::zcMMTimer1Timer(TObject *Sender)
{
unsigned int vl; int mcierr,ii,jj;
zcMMTimer1->Enabled=false;
wvbfr[0]='\0'; wvbfr[1]='\0'; wvbfr[2]='\0'; wvbfr[3]='\0';
wvhd.lpData=wvbfr; wvhd.dwBufferLength=4;
wvhd.dwLoops=0; wvhd.dwFlags=0; waveInStop(phwo);
if (waveInPrepareHeader(phwo,&wvhd,sizeof(WAVEHDR))==MMSYSERR_NOERROR)
{
waveInAddBuffer(phwo,&wvhd,sizeof(WAVEHDR));
waveInStart(phwo);
}
}
//--------------------------------------------------------------------------
// In the form closequery event, put this :-
//--------------------------------------------------------------------------
-
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
zcMMTimer1->Enabled=false; waveInStop(phwo);
waveInUnprepareHeader(phwo,&wvhd,sizeof(WAVEHDR));
waveInClose(phwo); CanClose=true;
}
//--------------------------------------------------------------------------
-
Hey presto, the values in ProcessInput()'s mybf buffer are :-
Left Channel = mybf[0]
Right Channel=mybf[1]
with a range of -32767 to 32767 in each case.
I verified my results on a Soundblaster Live card. I have noticed that the
Realtek AC97 Soundcard on another PC did not work properly. It could be
indicative of faulty sound drivers. I'll try other PCs and report back.
However, the code above has been arrived at painstakingly. Thankyou
Microsoft!
--
Mark Jacobs
"iim" <imamsi...@yahoo.com.sg> wrote in message
news:40622392$1...@newsgroups.borland.com...
>
> I need a small program to measure the signal level from microphone via
sound card. Anybody can help ?
"Mark Jacobs" <markjremovethisspu...@critical.co.uk> wrote in
message news:406c...@newsgroups.borland.com...
Not all Soundcards have PEAKMETERS (SoundBlasters and AC97's do NOT have
them, and hence, cannot display a
level meter on the standard Windows mixer control), so this rules out the
methods discussed before. Is there a
way to periodically read 4 bytes from each channel on the soundcard's
output? It seems an absurdly simple
thing to do, but the grief it has caused me so far is incredible!!! ...