1

Is there any simple example (with explanations) of how to use LAME API in C? I did manage to use the following code (based on Is there any LAME c++ wraper\simplifier (working on Linux Mac and Win from pure code)?):

FILE *pcm = fopen(input_file, "rb");
FILE *mp3 = fopen(output_file, "wb");
size_t nread;
int ret, nwrite;

// 1. Get lame version (OPTIONAL)
printf("Using LAME v%s\n", get_lame_version());

const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;

short pcm_buffer[PCM_SIZE * 2];
unsigned char mp3_buffer[MP3_SIZE];

// 2. Initializing
lame_t lame = lame_init();

// 3. Do some settings (OPTIONAL)
// lame_set_in_samplerate(lame, 48000);
lame_set_VBR(lame, vbr_default);
// lame_set_VBR_quality(lame, 2);

// 4. Initialize parameters
ret = lame_init_params(lame);
if (ret < 0) {
    printf("Error occurred during parameters initializing. Code = %d\n",
            ret);
    return 1;
}

do {
    // Read PCM_SIZE of array
    nread = fread(pcm_buffer, 2 * sizeof(short), PCM_SIZE, pcm);
    if (nread != 0) {
        // 5. Encode
        int nsamples = nread;
        short buffer_l[nsamples];
        short buffer_r[nsamples];

        printf("nread = %d\n", nread);
        printf("pcm_buffer.length = %d\n", sizeof(pcm_buffer)/sizeof(short));

        int j = 0;
        int i = 0;
        for (i = 0; i < nsamples; i++) {
            buffer_l[i] = pcm_buffer[j++];
            buffer_r[i] = pcm_buffer[j++];

        }

        nwrite = lame_encode_buffer(lame, buffer_l, buffer_r, nread,
                mp3_buffer, MP3_SIZE);
    } else {
        // 6. Flush and give some final frames
        nwrite = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
    }

    if (nwrite < 0) {
        printf("Error occurred during encoding. Code = %d\n", nwrite);
        return 1;
    }

    fwrite(mp3_buffer, nwrite, 1, mp3);
} while (nread != 0);

// 7. Write INFO tag (OPTIONAL)
// lame_mp3_tags_fid(lame, mp3);

// 8. Free internal data structures
lame_close(lame);

fclose(mp3);
fclose(pcm);

But the thing is,

  1. I don't understand why use

    short pcm_buffer[PCM_SIZE * 2];
    fread(pcm_buffer, 2 * sizeof(short), PCM_SIZE, pcm);
    

    Instead of

    short pcm_buffer[PCM_SIZE * 2];
    fread(pcm_buffer, sizeof(short), PCM_SIZE * 2, pcm);
    
  2. If I have to use the first way, how use get such pcm_buffer in Java? I want to use JNI

  3. Is that a correct way to get 2 buffer (left and right)?

Thanks

Community
  • 1
  • 1
sancho21
  • 3,511
  • 1
  • 39
  • 45
  • I don't know LAME, but your first question's answer is that there is `PCM_SIZE * 2 * sizeof(short)` bytes of memory available. The first method reads that much. Your method reads half of it. – Shahbaz Jul 14 '12 at 16:44
  • Just updated my question. Code snippet's not fit here. – sancho21 Jul 14 '12 at 17:19

1 Answers1

0

1) I don't understand why use

pcm_buffer has space for PCM_SIZE*2 elements that each are sizeof(short) bytes large (typically 2 bytes). I.e. PCM_SIZE*2*sizeof(short) bytes in total.

That's why the fread is reading PCM_SIZE chunks of 2*sizeof(short), it's filling up the entire PCM_SIZE*2*sizeof(short) bytes in the buffer.

Michael
  • 57,169
  • 9
  • 80
  • 125
  • But as far as I know, fread second argument tells us that it will read 2 bytes (2 * sizeof short) and put that in a short (which there is allocation of 2*PCM_SIZE of shorts). How can that be possible to put 2 bytes into a single byte (this like assigning short a = two byte data). – sancho21 Jul 14 '12 at 17:05
  • The second argument specifies the size of each element to be read, i.e. 4 bytes (assuming a short is 2 bytes on your target system). The third argument specifies how many such elements that should be read. So all in all the code is filling up the entire buffer with each fread. – Michael Jul 14 '12 at 17:21