[win 32] loading dll (lame encoder)
Hi,
I'd like to know how I can load an external dll in C++ so I can use its API. Just for the record I would like to encode a WAVE file to MP3 so I have founfd this:
http://www.linuks.mine.nu/gnustep/de...ame-3.98.1/API
So I have downloaded the LAME encoder and this is what I have:
BladeMP3EncDLL.def
lame_enc.dll
readme.txt ehich reads:
Quote:
This is a pre-built DLL of libmp3lame from the lame-3.98
distribution.
This version was built with Visual Studio 2005 and exports
all of the current functions listed in lame.h.
To build, replace the file "lame-3.98.2\Dll\BladeMP3EncDLL.def"
in the LAME source code with the one in this archive and build
with Visual Studio.
so, how can I load the DLL?
thanks
Re: [win 32] loading dll (lame encoder)
Quote:
Originally Posted by
THEARTOFWEB
Hi,
I'd like to know how I can load an external dll in C++ so I can use its API. Just for the record I would like to encode a WAVE file to MP3 so I have founfd this:
http://www.linuks.mine.nu/gnustep/de...ame-3.98.1/API
So I have downloaded the LAME encoder and this is what I have:
BladeMP3EncDLL.def
lame_enc.dll
readme.txt ehich reads:
so, how can I load the DLL?
LoadLibrary/GetProcAddress.
Regards,
Paul McKenzie
Re: [win 32] loading dll (lame encoder)
Re: [win 32] loading dll (lame encoder)
Quote:
Originally Posted by
BobS0327
Thanks. A LoadLibrary, and a bunch of GetProcAddresses as I stated, but it gets to the point right away.
Regards,
Paul McKenzie
Re: [win 32] loading dll (lame encoder)
wow, that's great code to start! Since, I am going to do real time encoding while capturing audio with the waveForm API I was wondering wheter I myself could supply the dwSamples value to the function:
beInitStream(&bec, &dwSamples, &dwBufferSize, &hbe);
that's beacuse I would like to encode 88200 Bytes of wav at a time! (88200 is 44100 x 2, so, 1 second of audio stereo!)
when I try to read the values return by the beInitStream() function I get:
dwSamples: 2304
dwBufferSize: 8640 (mp3 buffer size)
By the way, what is dwsamples??
thanks
Re: [win 32] loading dll (lame encoder)
Quote:
By the way, what is dwsamples??
Judging from the Wav file format it probably has something to do with Wav block alignment. I.e. 4 x 12 x 48 = 2304 in the Layer 1: nBlockAlign of the Wav format.
Re: [win 32] loading dll (lame encoder)
by the way, what are 4, 12 and 48??
Re: [win 32] loading dll (lame encoder)
I would suggest that you download the source code for the DLL and review the beInitStream function to determine exactly how dwSamples is calculated.
Re: [win 32] loading dll (lame encoder)
// Define WAVEFORMATEX Structure:
WAVEFORMATEX wf;
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.wBitsPerSample = 16;
wf.nChannels = 2
wf.nSamplesPerSec = 44100
wf.nBlockAlign = (wf.nChannels * wf.wBitsPerSample) / 8;
wf.nAvgBytesPerSec = (wf.nSamplesPerSec * wf.nBlockAlign);
//
This mean "nAvgBytesPerSec" will be (DWORD) 176400 Bytes (per second)
My application does real time capturing from a given source and notify me thru a CALLBACK_EVENT when the (LPBYTE) buffer[176400] is filled and return the buffer:
while(1)
{
// CALLBACK EVENT
WaitForSingleObject(hevent, INFINITE);
// sizeof(buffer) = 176400
// encode buffer
}
The code above is the barebones of my capturing & encoding programm! On the other hand, I have found out that the Lame-enc DLL returns me some values telling me how many samples it is willing to encode when I first init it!
PBYTE pMP3Buffer =NULL;
PSHORT pWAVBuffer =NULL;
beInitStream(&beConfig, &dwSamples, &dwMP3Buffer, &hbeStream);
// Allocate MP3 buffer
pMP3Buffer = new BYTE[dwMP3Buffer]; // (dword) 8640
// Allocate WAV buffer
pWAVBuffer = new SHORT[dwSamples]; // (dword) 2304
whereas 2304 is too little for me! Also, 176400 / 2304 = 76,56 as I don't really get it!
I have found some code on the internet to show how to use the DLL to encode a WAVE file. What the code basically does it the following:
// Convert All PCM samples
while ( (dwRead = fread(pWAVBuffer,sizeof(SHORT),dwSamples,pFileIn)) > 0 )
{
// Encode samples
beEncodeChunk(hbeStream, dwRead, pWAVBuffer, pMP3Buffer, &dwWrite);
// Save chunk
fwrite(pMP3Buffer,1,dwWrite,pFileOut);
}
It basically reads "dwSamples" in "pWAVBuffer" and sends it to the encoder...
I am really stuck at this. I wish I could push as many samples as I want! (176400)
thanks
Re: [win 32] loading dll (lame encoder)
Quote:
I wish I could push as many samples as I want! (176400)
If you carefully read Lame's source code, you'll see that Lame calculates dwSamples as 1152 x 2 = 2304, where 2 is the number of channels. One would be mono and two would be stereo. The 1152 at first appears to be a Lame "magic number". But it's not. The MP3 Modified Discrete Cosine Transform (MDCT) encoder uses this value in MPEG1 Layer 3 (MP3) to store a sound clip in frames of 1152 samples. Thus, I would have absolutely no idea on how to get 176,400 samples when lame determines that 2304 is the max sampling rate according to a MP3 standard.
Re: [win 32] loading dll (lame encoder)
Quote:
Originally Posted by
BobS0327
Thus, I would have absolutely no idea on how to get 176,400 samples when lame determines that 2304 is the max sampling rate according to a MP3 standard.
well, at least this takes me somewhere! 2304 is the max sampling rate, but it could be less like 2205 this means I should call the encode chunk 80 times for each 176400 chunk
Re: [win 32] loading dll (lame encoder)
Ok, I am gonna use 2304 bytes at a time
Now, I have problems encoding the data form the WAVEform API (internal mic) I thought I would try to use the same code I used to encode an mp3 from a WAVE file as shown below:
Code:
// BE_ERR beInitStream( PBE_CONFIG pbeConfig,
PDWORD dwSamples,
PDWORD dwBufferSize,
PHBE_STREAM phbeStream );
// BE_ERR beEncodeChunk( HBE_STREAM hbeStream,
DWORD nSamples,
PSHORT pSamples,
PBYTE pOutput,
PDWORD pdwOutput );
// Init the MP3 Stream
beInitStream(&bec, &dwSamples, &dwMP3Buffer, &hbeStream);
// Allocate MP3 buffer
pMP3Buffer = new BYTE[dwMP3Buffer];
// Allocate WAV buffer
pWAVBuffer = new SHORT[dwSamples];
// dwSamples = 2304, dwRead ritorna 2304
while ( ( dwRead = fread(pWAVBuffer, sizeof(SHORT), dwSamples, pFileIn)) > 0 )
{
// Encode samples
beEncodeChunk(hbeStream, dwRead, pWAVBuffer, pMP3Buffer, &dwWrite);
// Write dwWrite bytes that are returned in tehe pMP3Buffer to disk
fwrite(pMP3Buffer, 1, dwWrite, pFileOut);
}
So I went like this:
Code:
// dwSamples is 2304
// buff[k].lpData is 6912 bytes long (LPSTR)
// I'm gonna read it 2304 bytes at a time (3 times)
// then store its value in PSHORT pWAVChunk = new SHORT[dwSamples]
// Loop...
int dwChunkSeek = 0;
int dwLoop = 0;
int k = 0;
while(1)
{
// CALLBACK EVENT
WaitForSingleObject(hevent, INFINITE);
if(buff[k].dwFlags & WHDR_DONE)
{
// Encode chunk by chunk
while(dwLoop < 3)
{
// copy part of the buffer
memcpy(pWAVChunk, buff[k].lpData + dwChunkSeek, 2304);
// Encode samples
beEncodeChunk(hbeStream, 2304, pWAVChunk, pMP3Buffer,&dwWrite);
// Save
hFile.write((LPSTR)pMP3Buffer, dwWrite);
dwChunkSeek += 2304;
++dwLoop;
}
dwLoop = 0;
dwChunkSeek = 0;
waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
}
}
but I get a bad mp3 file with noise only...
probably I got something wrong here:
memcpy(pWAVChunk, buff[k].lpData + dwChunkSeek, 2304);
or here?
beEncodeChunk(hbeStream, 2304, pWAVChunk, pMP3Buffer,&dwWrite);
thanks
Re: [win 32] loading dll (lame encoder)
I'm sorry, that is not working either...do you think I should cast? what I
dont get is the following
Code:
// dwSamples = 2304;
dwRead = fread(pWAVBuffer, sizeof(SHORT), dwSamples, pFileIn));
basically that is reading sizeof(SHORT)*dwSamples (4608). Yet, dwRead is
2304...
I record the same time a WAVE and MP3 file, this is the main code for my
project:
Code:
while(1)
{
if(stop_thread_flag)
break;
// CALLBACK EVENT
WaitForSingleObject(hevent, INFINITE);
if(buff[k].dwFlags & WHDR_DONE && !stop_thread_flag)
{
// Save WAVE
hFile2.write(buff[k].lpData, buff[k].dwBytesRecorded);
dwWAVBufferCounter += buff[k].dwBytesRecorded;
// Encode chunk by chunk (dwLoop = 0)
while(dwLoop <= 3)
{
// copy part of the buffer...PSHORT pWAVChunk = new SHORT[dwSamples]
memcpy(pWAVChunk, buff[k].lpData + dwChunkSeek*sizeof(SHORT), 2304);
// Encode samples
result = beEncodeChunk(hbeStream, 2304, pWAVChunk, pMP3Buffer,
&dwWrite);
//printf("%d -> %d \n", hashChunk[dwLoop], dwWrite);
// Save MP3
hFile.write((LPSTR)pMP3Buffer, dwWrite);
dwChunkSeek += 2304;
dwMP3BufferCounter += dwWrite;
++dwLoop;
}
dwLoop = 0;
dwChunkSeek = 0;
waveInAddBuffer(hwi, &buff[k], sizeof(WAVEHDR));
}
if(k == num_buffers -1)
k = 0;
else
k++;
}
I am really stuck at that :-(
Re: [win 32] loading dll (lame encoder)
Quote:
Originally Posted by
THEARTOFWEB
I'm sorry, that is not working either...do you think I should cast? what I
dont get is the following
Code:
// dwSamples = 2304;
dwRead = fread(pWAVBuffer, sizeof(SHORT), dwSamples, pFileIn));
basically that is reading sizeof(SHORT)*dwSamples (4608).
No. The third parameter to fread() is the count of the number of items to read, where each item is sizeof(SHORT). So the return value is returning to you the number of sizeof(SHORT) items read, which is 2304.
http://www.cplusplus.com/reference/c.../cstdio/fread/
Regards,
Paul McKenzie
Re: [win 32] loading dll (lame encoder)
Quote:
Now, I have problems encoding the data form the WAVEform API (internal mic) I thought I would try to use the same code I used to encode an mp3 from a WAVE but I get a bad mp3 file with noise only.
How are you capturing the mic input??