CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Join Date
    Dec 2009
    Posts
    161

    [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:

    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

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [win 32] loading dll (lame encoder)

    Quote Originally Posted by THEARTOFWEB View Post
    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

  3. #3
    Join Date
    Apr 2004
    Posts
    102

    Re: [win 32] loading dll (lame encoder)


  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [win 32] loading dll (lame encoder)

    Quote Originally Posted by BobS0327 View Post
    Thanks. A LoadLibrary, and a bunch of GetProcAddresses as I stated, but it gets to the point right away.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Dec 2009
    Posts
    161

    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

  6. #6
    Join Date
    Apr 2004
    Posts
    102

    Re: [win 32] loading dll (lame encoder)

    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.

  7. #7
    Join Date
    Dec 2009
    Posts
    161

    Re: [win 32] loading dll (lame encoder)

    by the way, what are 4, 12 and 48??

  8. #8
    Join Date
    Apr 2004
    Posts
    102

    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.

  9. #9
    Join Date
    Dec 2009
    Posts
    161

    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

  10. #10
    Join Date
    Apr 2004
    Posts
    102

    Re: [win 32] loading dll (lame encoder)

    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.

  11. #11
    Join Date
    Dec 2009
    Posts
    161

    Re: [win 32] loading dll (lame encoder)

    Quote Originally Posted by BobS0327 View Post
    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

  12. #12
    Join Date
    Dec 2009
    Posts
    161

    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

  13. #13
    Join Date
    Dec 2009
    Posts
    161

    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 :-(

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [win 32] loading dll (lame encoder)

    Quote Originally Posted by THEARTOFWEB View Post
    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

  15. #15
    Join Date
    Apr 2004
    Posts
    102

    Re: [win 32] loading dll (lame encoder)

    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??

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured