Question

Subsequent to my question posted here, further investigation into LAME with gdb revealed that at any given time, only 576 samples are read from the input pcm file. However, these samples are used to populate a 2304 1D or 2*1152 2D array. It is this conversion that I am not able to understand. I am posting the relevant code here and request an explanation. I have explained parts of the code and inserted questions into the code as ???.

  samples_read = read_samples_pcm(global.musicin, insamp, num_channels * samples_to_read);
  /* global.musicin = FILE pointer to input pcm file.
   * insamp is a 1D int array of [2*1152] size.
   * num_channels = 1. samples_to_read = 576. */
    if (samples_read < 0) {
        return samples_read;
    }
    p = insamp + samples_read;
    samples_read /= num_channels;  /*samples_read = 576 after this step. prior to this it is optimized out.*/
    if (buffer != NULL) { /* output to int buffer */
        if (num_channels == 2) {
            for (i = samples_read; --i >= 0;) {
                buffer[1][i] = *--p;
                buffer[0][i] = *--p;
            }
        }
        else if (num_channels == 1) {
            memset(buffer[1], 0, samples_read * sizeof(int));
            for (i = samples_read; --i >= 0;) {
                buffer[0][i] = *--p;
                /*??? Is this line a fancy way of copying first 576 samples of insamp into buffer[0]?*/
            }
        }
        else
            assert(0);
    }

The function read_samples_pcm is defined so:

static int
read_samples_pcm(FILE * const musicin, int sample_buffer[2304], int samples_to_read)
{
    int     samples_read;

    samples_read = sf_read_int((SNDFILE *) musicin, sample_buffer, samples_to_read);

#if 0
    switch (global.pcmbitwidth) {
    case 8:
        for (i = 0; i < samples_read; i++)
            sample_buffer[i] <<= (8 * sizeof(int) - 8);
        break;
    case 16:  /*input pcm is 16 bit say.*/
        for (i = 0; i < samples_read; i++)
            sample_buffer[i] <<= (8 * sizeof(int) - 16); /*??? what is going on? */
        break;
    case 24:
        for (i = 0; i < samples_read; i++)
            sample_buffer[i] <<= (8 * sizeof(int) - 24);
        break;
    case 32:
        break;
    default:
        if (silent < 10) {
            error_printf("Only 8, 16, 24 and 32 bit input files supported \n");
        }
        exit(1);
    }
#endif

    return samples_read;
}
Was it helpful?

Solution

/??? Is this line a fancy way of copying first 576 samples of insamp into buffer[0]?/

Basically, yes. It's just copying the data end->start rather than the usual start->end order. I'm not sure but I think some people prefer this for memory cache performance reasons.

/*??? what is going on? */

It's scaling the 16-bit input to a 32-bit number. Let's walk through it:

sample_buffer[i] <<= (8 * sizeof(int) - 16);

If sizeof(int) is 4 bytes, 8 * 4 - 16 = 16. Thus, shift the 16-bit number left by 16 in order to scale it to a 32-bit number. If sizeof(int) is 8 bytes, 8 * 8 - 16 = 48. If ints are 64-bit, a left shift by 48 bits is necessary.

I'm not sure if I've answered all your questions here. Feel free to follow up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top