00001 #include "mpeg3private.h"
00002 #include "mpeg3protos.h"
00003
00004 #include <stdlib.h>
00005
00006
00007 mpeg3_pcm_t* mpeg3_new_pcm()
00008 {
00009 mpeg3_pcm_t *result = calloc(1, sizeof(mpeg3_pcm_t));
00010 return result;
00011 }
00012
00013
00014
00015 void mpeg3_delete_pcm(mpeg3_pcm_t *audio)
00016 {
00017 free(audio);
00018 }
00019
00020
00021 int mpeg3_pcm_check(unsigned char *header)
00022 {
00023 if(header[0] == ((MPEG3_PCM_START_CODE & 0xff000000) >> 24) &&
00024 header[1] == ((MPEG3_PCM_START_CODE & 0xff0000) >> 16) &&
00025 header[2] == ((MPEG3_PCM_START_CODE & 0xff00) >> 8) &&
00026 header[3] == (MPEG3_PCM_START_CODE & 0xff))
00027 return 0;
00028 else
00029 return 1;
00030 }
00031
00032
00033
00034
00035 int mpeg3_pcm_header(mpeg3_pcm_t *audio, unsigned char *data)
00036 {
00037 if(mpeg3_pcm_check(data)) return 0;
00038
00039
00040 audio->samplerate = *(int32_t*)(data + 4);
00041 audio->bits = *(int32_t*)(data + 8);
00042 audio->channels = *(int32_t*)(data + 12);
00043 audio->framesize = *(int32_t*)(data + 16);
00044
00045 return audio->framesize;
00046 }
00047
00048 int mpeg3audio_dopcm(mpeg3_pcm_t *audio,
00049 char *frame,
00050 int frame_size,
00051 float **output,
00052 int render)
00053 {
00054 int bytes_per_sample = audio->bits / 8 * audio->channels;
00055 int output_size = (frame_size - PCM_HEADERSIZE) / bytes_per_sample;
00056 int i, j;
00057
00058
00059 if(render)
00060 {
00061 for(i = 0; i < audio->channels; i++)
00062 {
00063
00064 float *output_channel = output[i];
00065
00066 switch(audio->bits)
00067 {
00068 case 16:
00069 {
00070
00071 unsigned char *input = frame +
00072 PCM_HEADERSIZE +
00073 audio->bits / 8 * i;
00074 int16_t sample;
00075
00076 for(j = 0; j < output_size; j++)
00077 {
00078 sample = ((int16_t)(input[0])) << 8;
00079 sample |= input[1];
00080 *output_channel = (float)sample / 32767.0;
00081 input += bytes_per_sample;
00082 output_channel++;
00083 }
00084
00085 }
00086 break;
00087 }
00088 }
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 return output_size;
00100 }