int mpeg3audio_do_pcm(mpeg3audio_t *audio) { int i, j, k; MPEG3_INT16 sample; int frame_samples = (audio->framesize - 3) / audio->channels / 2; if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, frame_samples * audio->channels * 2)) return 1; /* Need more room */ if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels) { mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels); } k = 0; for(i = 0; i < frame_samples; i++) { for(j = 0; j < audio->channels; j++) { sample = ((MPEG3_INT16)(audio->ac3_buffer[k++])) << 8; sample |= audio->ac3_buffer[k++]; audio->pcm_sample[audio->pcm_point + i * audio->channels + j] = (mpeg3_real_t)sample / 32767; } } audio->pcm_point += frame_samples * audio->channels; return 0; }
int mpeg3audio_read_ac3_header(mpeg3audio_t *audio) { unsigned int code, crc; unsigned int i; mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi); /* Get the sync code */ code = mpeg3bits_getbits(audio->astream, 16); while(!mpeg3bits_eof(audio->astream) && code != MPEG3_AC3_START_CODE) { code <<= 8; code &= 0xffff; code |= mpeg3bits_getbits(audio->astream, 8); } if(mpeg3bits_eof(audio->astream)) return 1; /* Get crc1 - we don't actually use this data though */ /* The crc can be the same as the sync code or come after a sync code repeated twice */ crc = mpeg3bits_getbits(audio->astream, 16); /* Got the sync code. Read the entire frame into a buffer if possible. */ if(audio->avg_framesize > 0) { if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, audio->framesize - 4)) return 1; mpeg3bits_use_ptr(audio->astream, audio->ac3_buffer); } /* Get the sampling rate code */ audio->sampling_frequency_code = mpeg3bits_getbits(audio->astream, 2); /* Get the frame size code */ audio->ac3_framesize_code = mpeg3bits_getbits(audio->astream, 6); audio->bitrate = framesize_codes[audio->ac3_framesize_code].bit_rate; audio->avg_framesize = audio->framesize = 2 * framesize_codes[audio->ac3_framesize_code].frm_size[audio->sampling_frequency_code]; /* Check the AC-3 version number */ bsi->bsid = mpeg3bits_getbits(audio->astream, 5); /* Get the audio service provided by the steram */ bsi->bsmod = mpeg3bits_getbits(audio->astream, 3); /* Get the audio coding mode (ie how many channels)*/ bsi->acmod = mpeg3bits_getbits(audio->astream, 3); /* Predecode the number of full bandwidth channels as we use this * number a lot */ bsi->nfchans = mpeg3_ac3_acmodes[bsi->acmod]; audio->channels = bsi->nfchans; /* If it is in use, get the centre channel mix level */ if((bsi->acmod & 0x1) && (bsi->acmod != 0x1)) bsi->cmixlev = mpeg3bits_getbits(audio->astream, 2); /* If it is in use, get the surround channel mix level */ if(bsi->acmod & 0x4) bsi->surmixlev = mpeg3bits_getbits(audio->astream, 2); /* Get the dolby surround mode if in 2/0 mode */ if(bsi->acmod == 0x2) bsi->dsurmod= mpeg3bits_getbits(audio->astream, 2); /* Is the low frequency effects channel on? */ bsi->lfeon = mpeg3bits_getbits(audio->astream, 1); /* Get the dialogue normalization level */ bsi->dialnorm = mpeg3bits_getbits(audio->astream, 5); /* Does compression gain exist? */ bsi->compre = mpeg3bits_getbits(audio->astream, 1); if (bsi->compre) { /* Get compression gain */ bsi->compr = mpeg3bits_getbits(audio->astream, 8); } /* Does language code exist? */ bsi->langcode = mpeg3bits_getbits(audio->astream, 1); if (bsi->langcode) { /* Get langauge code */ bsi->langcod = mpeg3bits_getbits(audio->astream, 8); } /* Does audio production info exist? */ bsi->audprodie = mpeg3bits_getbits(audio->astream, 1); if (bsi->audprodie) { /* Get mix level */ bsi->mixlevel = mpeg3bits_getbits(audio->astream, 5); /* Get room type */ bsi->roomtyp = mpeg3bits_getbits(audio->astream, 2); } /* If we're in dual mono mode then get some extra info */ if (bsi->acmod == 0) { /* Get the dialogue normalization level two */ bsi->dialnorm2 = mpeg3bits_getbits(audio->astream, 5); /* Does compression gain two exist? */ bsi->compr2e = mpeg3bits_getbits(audio->astream, 1); if (bsi->compr2e) { /* Get compression gain two */ bsi->compr2 = mpeg3bits_getbits(audio->astream, 8); } /* Does language code two exist? */ bsi->langcod2e = mpeg3bits_getbits(audio->astream, 1); if (bsi->langcod2e) { /* Get langauge code two */ bsi->langcod2 = mpeg3bits_getbits(audio->astream, 8); } /* Does audio production info two exist? */ bsi->audprodi2e = mpeg3bits_getbits(audio->astream, 1); if (bsi->audprodi2e) { /* Get mix level two */ bsi->mixlevel2 = mpeg3bits_getbits(audio->astream, 5); /* Get room type two */ bsi->roomtyp2 = mpeg3bits_getbits(audio->astream, 2); } } /* Get the copyright bit */ bsi->copyrightb = mpeg3bits_getbits(audio->astream, 1); /* Get the original bit */ bsi->origbs = mpeg3bits_getbits(audio->astream, 1); /* Does timecode one exist? */ bsi->timecod1e = mpeg3bits_getbits(audio->astream, 1); if(bsi->timecod1e) bsi->timecod1 = mpeg3bits_getbits(audio->astream, 14); /* Does timecode two exist? */ bsi->timecod2e = mpeg3bits_getbits(audio->astream, 1); if(bsi->timecod2e) bsi->timecod2 = mpeg3bits_getbits(audio->astream, 14); /* Does addition info exist? */ bsi->addbsie = mpeg3bits_getbits(audio->astream, 1); if(bsi->addbsie) { /* Get how much info is there */ bsi->addbsil = mpeg3bits_getbits(audio->astream, 6); /* Get the additional info */ for(i = 0; i < (bsi->addbsil + 1); i++) bsi->addbsi[i] = mpeg3bits_getbits(audio->astream, 8); } if(mpeg3bits_eof(audio->astream)) { mpeg3bits_use_demuxer(audio->astream); return 1; } return 0; // return mpeg3bits_error(audio->astream); }