0
0

I have a question not really directly relating to fmod, but you guys are always pretty helpful! :)

I am trying to take PCM data from an FMOD sample and encode it into an ogg using the Vorbis lib that Al Faber wrote that is quite famous on the net (xiph.org) ….

I just have a confusion on some parameters and I believe I mix up the BYTES and SAMPLES and BITS PER SAMPLE quite a bit….

Anyways here is the basic run down:

vbConfig.format.VBV1.dwStructVersion = VB_ENC_STRUCT_VERSION;
vbConfig.format.VBV1.dwStructSize = sizeof(vbConfig);
vbConfig.format.VBV1.dwSampleRate = 22050;
vbConfig.format.VBV1.lMinBitRate = 128;
vbConfig.format.VBV1.lNomBitRate = 192;
vbConfig.format.VBV1.lMaxBitRate = 256;
vbConfig.format.VBV1.dwInfoMode = VB_MODE_C;
vbConfig.format.VBV1.dwChannels = 2;

I use the above struct to feed in the number of samples
and buffer sizes I should be encoding with, I assumed the SAMPLES is the number of SAMPLES and not bytes of each encoding buffer

vbEncOpen(&vbConfig, &vbAlbumInfo, &VB_dwSamples, &dwOggBuffer,&hvbStream);

I then create the buffers
pOggBuffer = new BYTE[dwOggBuffer];
VB_pWAVBuffer = new SHORT[VB_dwSamples];

I then load in the sample with standard fmod calls where nLength is the number of bytes of the wav file
pSample = FSOUND_Sample_Load( FSOUND_FREE, data, FSOUND_NORMAL | FSOUND_LOADMEMORY , nLength );

I get the actual byte length of the sample itself [data chunk]?
I bit shift by two because I recording the wav file using 16 bits per sample or 2 bytes per sample
nBytes = FSOUND_Sample_GetLength( pSample ) << 2;

and then I start crunching through the wav file
while ( ( nCurrent < nBytes) )
{
i use the number of samples from the config to figure out how many bytes to encode at once and do the standard fmod lock for the PCM data….
DWORD dwBytesToSample = VB_dwSamples * 2 ;
FSOUND_Sample_Lock( pSample, nPosition, dwBytesToSample, &ptr1, &ptr2, &nLengthHead, &nLengthTail);

  I copy the pcm data into a wav buffer using the length of bytes I locked....
  memcpy(VB_pWAVBuffer, ptr1, dwBytesToSample );

 and then I call the encoder with the number of bytes to copy... Or does anyone know if I pass the number of samples??

VB_dwRead = dwBytesToSample;
vbEncWrite(hvbStream, VB_dwRead, VB_pWAVBuffer, pOggBuffer, &amp;VB_dwWrite);

i write the returned buffer to a file and continue on my merry way 
fwrite( pOggBuffer, 1, VB_dwWrite, pFileOut);

nPosition += (dwBytesToSample);
FSOUND_Sample_Unlock( pSample, &amp;ptr1, &amp;ptr2, nLengthHead, nLengthTail);

}

The problem is that the file comes out totally hosed, a repetetive high pitch tick sound is heard as if the sampling rates were all screwed up…. but I know its not the sampling rate because that would make the ogg sound like a chipmunk…..

I think I am messing up my buffer sizes all over the place :/

  • You must to post comments
0
0

[code:2pwzd4r6]
while ( ( nCurrent < nBytes) )
{
FSOUND_Sample_Lock( pSample, nPosition, VB_dwSamples, &ptr1, &ptr2, &nLengthHead, &nLengthTail);

I copy the pcm data into a wav buffer using the length of bytes I locked....
memcpy(VB_pWAVBuffer, ptr1, VB_dwSamples);

and then I call the encoder with the number of bytes to copy... Or does anyone know if I pass the number of samples??

VB_dwRead = VB_dwSamples >> 1;
vbEncWrite(hvbStream, VB_dwRead, VB_pWAVBuffer, pOggBuffer, &VB_dwWrite);

i write the returned buffer to a file and continue on my merry way
fwrite( pOggBuffer, 1, VB_dwWrite, pFileOut);

nPosition += VB_dwSamples;
FSOUND_Sample_Unlock( pSample, &ptr1, &ptr2, nLengthHead, nLengthTail);
}
[/code:2pwzd4r6]

  • You must to post comments
0
0

Hmm when I make the changed you suggest and encode the wav files I have it creates a 0 length data .ogg file….

How wierd.. At least that is the error goldwave returns. Winamp just chokes on them.

Wav files were made with 22050, 16 bits, 2 channels / stereo so I think all of my constants are right. I find it interesting that you changed :
VB_dwRead = VB_dwSamples >> 1;
though.

  • You must to post comments
0
0

it is what i am doing and it works fine, you can check a simple encoder [url=http://starnetasso.free.fr/Upload/Encodeur.zip:1h46d0vq]here[/url:1h46d0vq].

  • You must to post comments
0
0

Hmmm, I just tried your record.exe and it did the same thing as my program did. Check out the wav file:

ftp://ftp.gamehouse.com/RECORDING_A.WAV

Recorded at: 22050 Hz, 2 Channels, 16 bits per sample
Length: 0:01

  • You must to post comments
0
0

Oh ok, it is because the file is a 22050 hz wav, you must init Fmod to 22050 and set the vorbis encoder to 22050 too (the encoder example doesn’t do resampling, it was meant to be use only with 44.1 khz files). Here is a modified snippet :

[code:mhouxzgn]
int WriteOGG(const char *FileInput, VB_CONFIG output)
{

FILE            *fp2;
FILE            *pFileOut;
int             length;
char            *data;
unsigned int    len1, len2 = 0;
unsigned int    sample_len;
DWORD           pos;                    // position in the data

FSOUND_SAMPLE   *sample;
VB_CONFIG       newConfig;


    memset(&amp;newConfig,0,sizeof(output));                    // clear all fields 
    newConfig = output;

    VB_hDLL=LoadLibrary(&quot;.\\vorbis.dll&quot;);

    // Get Interface functions
    vbEncOpen   = (VBENCOPEN)   GetProcAddress(VB_hDLL, TEXT_VBENCOPEN);
    vbEncWrite  = (VBENCWRITE)  GetProcAddress(VB_hDLL, TEXT_VBENCWRITE);
    vbEncClose  = (VBENCCLOSE)  GetProcAddress(VB_hDLL, TEXT_VBENCCLOSE);
    vbVersion   = (VBVERSION)   GetProcAddress(VB_hDLL, TEXT_VBVERSION);

    // Check if all interfaces are present
    if( !   vbEncOpen || !vbEncWrite || !vbEncClose || !vbVersion)
    {
        printf(&quot;Unable to get Vorbis interfaces&quot;);
        exit(1);
    }

    // Get the version number
    vbVersion(&amp;VB_Version);

    // Open OGG file
    if (!(pFileOut=fopen(&quot;out.ogg&quot;,&quot;wb+&quot;))) 
    {
        Error(&quot;Can't create file&quot;);
        return 0;
    }

    // get numsample to encode en prepare for encoding
    err = vbEncOpen(&amp;newConfig, &amp;vbAlbumInfo, &amp;VB_dwSamples,&amp;dwOggBuffer,&amp;hvbStream);

    // Check result
    if(err != VB_ERR_OK)
    {
        //ERROR
        Error(&quot;OGG::ENCODE : Can't create file&quot;);
        return 0;
    }

    // Allocate OGG buffer
    pOggBuffer = new BYTE[dwOggBuffer];

    // Allocate WAV buffer
    VB_pWAVBuffer = new SHORT[VB_dwSamples];

    // get filesize and file data
    fp2 = fopen(FileInput, &quot;rb&quot;);
    if (!fp2)
    {
        printf(&quot;Error!\n&quot;);
        printf(&quot;File Not Found\n&quot;);
        FSOUND_Close();
        return 1;
    }
    fseek(fp2, 0, SEEK_END);
    length = ftell(fp2);
    fseek(fp2, 0, SEEK_SET);

    data = (char *)malloc(length);
    fread(data, length, 1, fp2);
    fclose(fp2);

    // sample handle
    sample = FSOUND_Sample_Load(FSOUND_FREE, data, FSOUND_NORMAL | FSOUND_LOADMEMORY , length);
    // length of the sample 
    sample_len = FSOUND_Sample_GetLength(sample) &lt;&lt; 2;    //  &lt;&lt; 2 convert samples to bytes

    pos = 0;

while (!_kbhit() &amp;&amp; ( pos &lt; sample_len) ) {
    void *ptr1, *ptr2;

    FSOUND_Sample_Lock(sample, pos, VB_dwSamples, &amp;ptr1, &amp;ptr2, &amp;len1, &amp;len2);

    // now copy input into buffer 
    memcpy(VB_pWAVBuffer, ptr1, VB_dwSamples );
    //we now have a full buffer, pass it to the ogg encoder
    VB_dwRead = VB_dwSamples / 2;
    err = vbEncWrite(hvbStream, VB_dwRead, VB_pWAVBuffer, pOggBuffer, &amp;VB_dwWrite);

    // Check result
    if(err != BE_ERR_SUCCESSFUL)
    {
        vbEncClose(hvbStream,pOggBuffer,&amp;VB_dwWrite);
        printf(&quot;OGG::ENCODE : beEncodeChunk() failed (%lu)&quot;, err);
        break;
    }

    int numwritten;
    if(numwritten=fwrite(pOggBuffer,1,VB_dwWrite,pFileOut) != VB_dwWrite)
    {
        vbEncClose(hvbStream,pOggBuffer,&amp;VB_dwWrite);
    }

    // update the position
    pos += VB_dwSamples;
    // print some usefull informations
    printf(&quot;pos %09d numwritten %09d\r&quot;,pos, numwritten);
    // don't hoge the cpu :)
    Sleep(1); 

    // release the sample data
    FSOUND_Sample_Unlock(sample, &amp;ptr1, &amp;ptr2, len1, len2);
}

if (vbEncClose(hvbStream, pOggBuffer, &amp;VB_dwWrite) == VB_ERR_OK)
{
    int numwritten;
    if(numwritten=fwrite(pOggBuffer,1,VB_dwWrite,pFileOut) != VB_dwWrite)
    {
        printf(&quot;Output file write error\n&quot;);
    }      
}
free(data);
FSOUND_Sample_Free(sample);
printf(&quot;\nfinished !\n&quot;);

return 1;

}

// In the main part

memset(&vbAlbumInfo,0,sizeof(vbAlbumInfo));

                vbAlbumInfo.dwSize=sizeof(vbAlbumInfo);                             // local
                vbAlbumInfo.dwVersion=VB_ALB_STRUCT_VERSION;                        // local
                vbAlbumInfo.dwRecords=1;                                            // local

                vbAlbumInfo.infoRecord.dwSize= sizeof(vbAlbumInfo.infoRecord);
                vbAlbumInfo.infoRecord.dwVersion=VB_ALB_STRUCT_VERSION;             // local

                vbAlbumInfo.infoRecord.strArtist        = &quot;Artist&quot; ;
                vbAlbumInfo.infoRecord.strAlbum         = &quot;Album&quot;;
                vbAlbumInfo.infoRecord.strTitle         = &quot;Title&quot;;
                vbAlbumInfo.infoRecord.strComment       = &quot;Comment&quot;;
                vbAlbumInfo.infoRecord.strGenre         = &quot;Genre&quot;;
                vbAlbumInfo.infoRecord.strEncodedBy     = &quot;Encoded by KarLKoX&quot;;
                vbAlbumInfo.infoRecord.strDateTime      = &quot;15/05/2002&quot;;

                vbAlbumInfo.infoRecord.dwTrackNumber= 1;
                vbAlbumInfo.infoRecord.dwTotalTracks= 13;


                memset(&amp;vbConfig,0,sizeof(vbConfig));

                vbConfig.dwConfig                       = VB_CONFIG_VORBIS;
                vbConfig.format.VBV1.dwStructVersion    = VB_ENC_STRUCT_VERSION;
                vbConfig.format.VBV1.dwStructSize       = sizeof(vbConfig);     
                vbConfig.format.VBV1.dwSampleRate       = 22050;
                vbConfig.format.VBV1.lMinBitRate        = 0;
                vbConfig.format.VBV1.lNomBitRate        = 0;
                vbConfig.format.VBV1.lMaxBitRate        = 0;
                vbConfig.format.VBV1.dwInfoMode         = VB_MODE_C;
                vbConfig.format.VBV1.dwChannels         = 2;

                if (! WriteOGG(FileIn, vbConfig) )
                {  
                    printf(&quot;OGG ERROR !\n&quot;);
                    return;
                }  

[/code:mhouxzgn]

  • You must to post comments
Showing 5 results
Your Answer

Please first to submit.