void II_main_bit_allocation ( DOUBLE perm_smr[2][SBLIMIT], UINT scfsi[2][SBLIMIT], UINT bit_alloc[2][SBLIMIT], INT* adb, FRAME* pFrame, PSETTINGS pSettings ) { int noisy_sbs; int rq_db, av_db = *adb; // If mode equals to joint stereo, find the optimum jsbound setting if( pFrame->actual_mode == MPG_MD_JOINT_STEREO) { // Start with standard stereo setup pFrame->pHeader->mode = MPG_MD_STEREO; pFrame->pHeader->mode_ext = 0; pFrame->jsbound = pFrame->sblimit; // Calculate the required bits if((rq_db=II_bits_for_nonoise(perm_smr, scfsi, pFrame,0)) > *adb) { int mode_ext=4; // Were a few bits short, switch to joint stereo pFrame->pHeader->mode = MPG_MD_JOINT_STEREO; // Start with mode extention 3 (is decremented first in while loop) do { // Decrease mode extention mode_ext--; // Get new joint stereo subband boundary pFrame->jsbound = js_bound(pFrame->pHeader->lay, mode_ext); // Calculate the number of required bits with the new settings rq_db = II_bits_for_nonoise(perm_smr, scfsi, pFrame,0); // Check if we have enough bits, and if we still can lower the // joint stereo subband boundary } while( (rq_db > *adb) && (mode_ext > 0)); pFrame->pHeader->mode_ext = mode_ext; } /* well we either eliminated noisy sbs or mode_ext == 0 */ } if (pSettings->bUseVbr == FALSE) { noisy_sbs = II_a_bit_allocation(perm_smr, scfsi, bit_alloc, adb, pFrame); } else { int nCurrentAllocTab=0; int nReqBits=0; int nChanIdx = pSettings->pFrame->nChannels-1; int i; // Start with minimum bitrate for (i=0;i<15;i++) { if ( pSettings->nMinBitRateIndex<=AllowedBrIdx[nChanIdx][i]) break; } pFrame->pHeader->bitrate_index=AllowedBrIdx[nChanIdx][i++]; // Recalculate the sbLimit and select proper ALLOC table hdr_to_frps(pFrame); // Determine the available bits for this frame, with current bitrate settings *adb = available_bits(pSettings); // Work out how many bits are needed for there to be no noise (ie all MNR > 0.0 + VBRLEVEL) // Keep bumping up the bitrate until we have more than this number of bits nCurrentAllocTab=pFrame->tab_num; if (pSettings->nFrame==192) { printf("break\n"); } nReqBits=II_bits_for_nonoise(perm_smr, scfsi, pFrame,pSettings->nVbrQuality+(nCurrentAllocTab==2)?20:0); // nReqBits=II_bits_for_nonoise(perm_smr, scfsi, pFrame,pSettings->nVbrQuality); if ( pSettings->nDebugLevel > 3 ) { DebugPrintf("VBR: req_bits=%i for bitrate setting %d adb=%d table=%d\n", nReqBits, bitrate[pFrame->pHeader->version][pFrame->pHeader->lay-1][pFrame->pHeader->bitrate_index], *adb, nCurrentAllocTab ); } while ( (nReqBits > *adb) && (AllowedBrIdx[nChanIdx][i]!=-1) ) { // We are not there yet, increase bit rate if possible pFrame->pHeader->bitrate_index=AllowedBrIdx[nChanIdx][i++]; // Limit to maximum bitrate index //if (pFrame->pHeader->bitrate_index > 14) // pFrame->pHeader->bitrate_index = 14; // Get new frame header parameters for this bitrate setting hdr_to_frps(pFrame); // Did we switch from alloc table? If so, calculate new required bits if (nCurrentAllocTab!=pFrame->tab_num) { nReqBits=II_bits_for_nonoise(perm_smr, scfsi, pFrame,pSettings->nVbrQuality); nCurrentAllocTab=pFrame->tab_num; } // Get the number of available bits for the new frame settings *adb = available_bits(pSettings); if ( pSettings->nDebugLevel > 2 ) { DebugPrintf("VBR: req_bits=%i for bitrate setting %d adb=%d table=%d\n", nReqBits, bitrate[pFrame->pHeader->version][pFrame->pHeader->lay-1][pFrame->pHeader->bitrate_index], *adb, nCurrentAllocTab ); } } noisy_sbs = VBR_bit_allocation(perm_smr, scfsi, bit_alloc, adb, pFrame,pSettings); } if ( pSettings->nDebugLevel > 2 ) { DebugPrintf("VBR frame=%d bitrate=%4d, noisy_sbs=%4d , adb is %3d sblimit=%2d sbound=%2d\n", pSettings->nFrame, bitrate[pFrame->pHeader->version][pFrame->pHeader->lay-1][pFrame->pHeader->bitrate_index], noisy_sbs, *adb, pFrame->sblimit, pFrame->jsbound ); } }
int main (int argc, char **argv) { typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT]; SBS *sb_sample; typedef double JSBS[3][SCALE_BLOCK][SBLIMIT]; JSBS *j_sample; #ifdef REFERENCECODE typedef double IN[2][HAN_SIZE]; IN *win_que; #endif typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT]; SUB *subband; frame_info frame; frame_header header; char original_file_name[MAX_NAME_SIZE]; char encoded_file_name[MAX_NAME_SIZE]; short **win_buf; static short buffer[2][1152]; static unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT]; static unsigned int scalar[2][3][SBLIMIT], j_scale[3][SBLIMIT]; static double smr[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT]; // FLOAT snr32[32]; short sam[2][1344]; /* was [1056]; */ int model, nch, error_protection; static unsigned int crc; int sb, ch, adb; unsigned long frameBits, sentBits = 0; unsigned long num_samples; int lg_frame; int i; /* Keep track of peaks */ int peak_left = 0; int peak_right = 0; char* mot_file = NULL; char* icy_file = NULL; /* Used to keep the SNR values for the fast/quick psy models */ static FLOAT smrdef[2][32]; static int psycount = 0; extern int minimum; sb_sample = (SBS *) mem_alloc (sizeof (SBS), "sb_sample"); j_sample = (JSBS *) mem_alloc (sizeof (JSBS), "j_sample"); #ifdef REFERENCECODE win_que = (IN *) mem_alloc (sizeof (IN), "Win_que"); #endif subband = (SUB *) mem_alloc (sizeof (SUB), "subband"); win_buf = (short **) mem_alloc (sizeof (short *) * 2, "win_buf"); /* clear buffers */ memset ((char *) buffer, 0, sizeof (buffer)); memset ((char *) bit_alloc, 0, sizeof (bit_alloc)); memset ((char *) scalar, 0, sizeof (scalar)); memset ((char *) j_scale, 0, sizeof (j_scale)); memset ((char *) scfsi, 0, sizeof (scfsi)); memset ((char *) smr, 0, sizeof (smr)); memset ((char *) lgmin, 0, sizeof (lgmin)); memset ((char *) max_sc, 0, sizeof (max_sc)); //memset ((char *) snr32, 0, sizeof (snr32)); memset ((char *) sam, 0, sizeof (sam)); global_init (); header.extension = 0; frame.header = &header; frame.tab_num = -1; /* no table loaded */ frame.alloc = NULL; header.version = MPEG_AUDIO_ID; /* Default: MPEG-1 */ programName = argv[0]; if (argc == 1) /* no command-line args */ short_usage (); else parse_args (argc, argv, &frame, &model, &num_samples, original_file_name, encoded_file_name, &mot_file, &icy_file); print_config (&frame, &model, original_file_name, encoded_file_name); uint8_t* xpad_data = NULL; if (mot_file) { if (header.dab_length <= 0) { fprintf(stderr, "Invalid XPAD length specified\n"); return 1; } int err = xpad_init(mot_file, header.dab_length + 1); if (err == -1) { fprintf(stderr, "XPAD reader initialisation failed\n"); return 1; } xpad_data = malloc(header.dab_length + 1); } /* this will load the alloc tables and do some other stuff */ hdr_to_frps (&frame); nch = frame.nch; error_protection = header.error_protection; unsigned long samps_read; while ((samps_read = get_audio(&musicin, buffer, num_samples, nch, &header)) > 0) { /* Check if we have new PAD data */ int xpad_len = 0; if (mot_file) { xpad_len = xpad_read_len(xpad_data, header.dab_length + 1); if (xpad_len == -1) { fprintf(stderr, "Error reading XPAD data\n"); xpad_len = 0; } else if (xpad_len == 0) { // no PAD available } else if (xpad_len == header.dab_length + 1) { // everything OK xpad_len = xpad_data[header.dab_length]; } else { fprintf(stderr, "xpad length=%d\n", xpad_len); abort(); } } unsigned long j; for (j = 0; j < samps_read; j++) { peak_left = MAX(peak_left, buffer[0][j]); } for (j = 0; j < samps_read; j++) { peak_right = MAX(peak_right, buffer[1][j]); } // We can always set the zmq peaks, even if the output is not // used, it just writes some variables zmqoutput_set_peaks(peak_left, peak_right); if (glopts.verbosity > 1) if (++frameNum % 10 == 0) { fprintf(stderr, "[%4u", frameNum); if (mot_file) { fprintf(stderr, " %s", xpad_len > 0 ? "p" : " "); } if (glopts.show_level) { fprintf(stderr, " (%6d|%-6d) ", peak_left, peak_right); fprintf(stderr, "] [%6s|%-6s]\r", level(0, &peak_left), level(1, &peak_right) ); } else { fprintf(stderr, "]\r"); } } fflush(stderr); win_buf[0] = &buffer[0][0]; win_buf[1] = &buffer[1][0]; adb = available_bits (&header, &glopts); lg_frame = adb / 8; if (header.dab_extension) { /* in 24 kHz we always have 4 bytes */ if (header.sampling_frequency == 1) header.dab_extension = 4; /* You must have one frame in memory if you are in DAB mode */ /* in conformity of the norme ETS 300 401 http://www.etsi.org */ /* see bitstream.c */ if (frameNum == 1) minimum = lg_frame + MINIMUM; adb -= header.dab_extension * 8 + (xpad_len ? xpad_len : FPAD_LENGTH) * 8; } { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*sb_sample)[ch][gr][bl][0] ); } #ifdef REFERENCECODE { /* Old code. left here for reference */ int gr, bl, ch; for (gr = 0; gr < 3; gr++) for (bl = 0; bl < SCALE_BLOCK; bl++) for (ch = 0; ch < nch; ch++) { window_subband (&win_buf[ch], &(*win_que)[ch][0], ch); filter_subband (&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]); } } #endif #ifdef NEWENCODE scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit); find_sf_max (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR_new (*sb_sample, *j_sample, frame.sblimit); scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit); } #else scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit); pick_scale (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR (*sb_sample, *j_sample, frame.sblimit); scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit); } #endif if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smr[ch][sb] = smrdef[ch][sb]; } } else { /* calculate the psymodel */ switch (model) { case -1: psycho_n1 (smr, nch); break; case 0: /* Psy Model A */ psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000); break; case 1: psycho_1 (buffer, max_sc, smr, &frame); break; case 2: for (ch = 0; ch < nch; ch++) { psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 3: /* Modified psy model 1 */ psycho_3 (buffer, max_sc, smr, &frame, &glopts); break; case 4: /* Modified Psycho Model 2 */ for (ch = 0; ch < nch; ch++) { psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 5: /* Model 5 comparse model 1 and 3 */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1 "); smr_dump(smr,nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3 "); smr_dump(smr,nch); break; case 6: /* Model 6 compares model 2 and 4 */ for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2 "); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4 "); smr_dump(smr,nch); break; case 7: fprintf(stdout,"Frame: %i\n",frameNum); /* Dump the SMRs for all models */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1"); smr_dump(smr, nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; case 8: /* Compare 0 and 4 */ psycho_n1 (smr, nch); fprintf(stdout,"0"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", model); exit (0); } if (glopts.quickmode == TRUE) /* copy the smr values and reuse them later */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smrdef[ch][sb] = smr[ch][sb]; } if (glopts.verbosity > 4) smr_dump(smr, nch); } #ifdef NEWENCODE sf_transmission_pattern (scalar, scfsi, &frame); main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts); //main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); write_header (&frame, &bs); //encode_info (&frame, &bs); if (error_protection) putbits (&bs, crc, 16); write_bit_alloc (bit_alloc, &frame, &bs); //encode_bit_alloc (bit_alloc, &frame, &bs); write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs); //encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization_new (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); //subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, // *subband, &frame); write_samples_new(*subband, bit_alloc, &frame, &bs); //sample_encoding (*subband, bit_alloc, &frame, &bs); #else transmission_pattern (scalar, scfsi, &frame); main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); encode_info (&frame, &bs); if (error_protection) encode_CRC (crc, &bs); encode_bit_alloc (bit_alloc, &frame, &bs); encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); sample_encoding (*subband, bit_alloc, &frame, &bs); #endif /* If not all the bits were used, write out a stack of zeros */ for (i = 0; i < adb; i++) put1bit (&bs, 0); if (xpad_len) { assert(xpad_len > 2); // insert available X-PAD for (i = header.dab_length - xpad_len; i < header.dab_length - FPAD_LENGTH; i++) putbits (&bs, xpad_data[i], 8); } for (i = header.dab_extension - 1; i >= 0; i--) { CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i); /* this crc is for the previous frame in DAB mode */ if (bs.buf_byte_idx + lg_frame < bs.buf_size) bs.buf[bs.buf_byte_idx + lg_frame] = crc; /* reserved 2 bytes for F-PAD in DAB mode */ putbits (&bs, crc, 8); } if (xpad_len) { /* The F-PAD is also given us by mot-encoder */ putbits (&bs, xpad_data[header.dab_length - 2], 8); putbits (&bs, xpad_data[header.dab_length - 1], 8); } else { putbits (&bs, 0, 16); // FPAD is all-zero } #if defined(VLC_INPUT) if (glopts.input_select == INPUT_SELECT_VLC) { vlc_in_write_icy(); } #endif frameBits = sstell (&bs) - sentBits; if (frameBits % 8) { /* a program failure */ fprintf (stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits / 8, frameBits % 8); fprintf (stderr, "If you are reading this, the program is broken\n"); fprintf (stderr, "Please report a bug.\n"); exit(1); } sentBits += frameBits; // Reset peak measurement peak_left = 0; peak_right = 0; } fprintf(stdout, "Main loop has quit with samps_read = %zu\n", samps_read); close_bit_stream_w (&bs); if ((glopts.verbosity > 1) && (glopts.vbr == TRUE)) { int i; #ifdef NEWENCODE extern int vbrstats_new[15]; #else extern int vbrstats[15]; #endif fprintf (stdout, "VBR stats:\n"); for (i = 1; i < 15; i++) fprintf (stdout, "%4i ", bitrate[header.version][i]); fprintf (stdout, "\n"); for (i = 1; i < 15; i++) #ifdef NEWENCODE fprintf (stdout,"%4i ",vbrstats_new[i]); #else fprintf (stdout, "%4i ", vbrstats[i]); #endif fprintf (stdout, "\n"); } fprintf (stderr, "Avg slots/frame = %.3f; b/smp = %.2f; bitrate = %.3f kbps\n", (FLOAT) sentBits / (frameNum * 8), (FLOAT) sentBits / (frameNum * 1152), (FLOAT) sentBits / (frameNum * 1152) * s_freq[header.version][header.sampling_frequency]); if (glopts.input_select == INPUT_SELECT_WAV) { if ( fclose (musicin.wav_input) != 0) { fprintf (stderr, "Could not close \"%s\".\n", original_file_name); exit (2); } } fprintf (stderr, "\nDone\n"); exit (0); }
int toolame_encode_frame( short buffer[2][1152], unsigned char *xpad_data, unsigned char *output_buffer, size_t output_buffer_size) { extern int minimum; if (encode_first_call) { hdr_to_frps(&frame); encode_first_call = 0; } const int nch = frame.nch; const int error_protection = header.error_protection; bs.output_buffer = output_buffer; bs.output_buffer_size = output_buffer_size; bs.output_buffer_written = 0; #ifdef REFERENCECODE short *win_buf[2] = {&buffer[0][0], &buffer[1][0]}; #endif int adb = available_bits (&header, &glopts); int lg_frame = adb / 8; if (header.dab_extension) { /* You must have one frame in memory if you are in DAB mode */ /* in conformity of the norme ETS 300 401 http://www.etsi.org */ /* see bitstream.c */ if (frameNum == 1) minimum = lg_frame + MINIMUM; adb -= header.dab_extension * 8 + (xpad_len ? xpad_len : FPAD_LENGTH) * 8; } { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*sb_sample)[ch][gr][bl][0] ); } #ifdef REFERENCECODE { /* Old code. left here for reference */ int gr, bl, ch; for (gr = 0; gr < 3; gr++) for (bl = 0; bl < SCALE_BLOCK; bl++) for (ch = 0; ch < nch; ch++) { window_subband (&win_buf[ch], &(*win_que)[ch][0], ch); filter_subband (&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]); } } #endif #ifdef NEWENCODE scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit); find_sf_max (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR_new (*sb_sample, *j_sample, frame.sblimit); scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit); } #else scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit); pick_scale (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR (*sb_sample, *j_sample, frame.sblimit); scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit); } #endif if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (int ch = 0; ch < nch; ch++) { for (int sb = 0; sb < SBLIMIT; sb++) smr[ch][sb] = smrdef[ch][sb]; } } else { /* calculate the psymodel */ switch (model) { case -1: psycho_n1 (smr, nch); break; case 0: /* Psy Model A */ psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000); break; case 1: psycho_1 (buffer, max_sc, smr, &frame); break; case 2: for (int ch = 0; ch < nch; ch++) { psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 3: /* Modified psy model 1 */ psycho_3 (buffer, max_sc, smr, &frame, &glopts); break; case 4: /* Modified Psycho Model 2 */ for (int ch = 0; ch < nch; ch++) { psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 5: /* Model 5 comparse model 1 and 3 */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1 "); smr_dump(smr,nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3 "); smr_dump(smr,nch); break; case 6: /* Model 6 compares model 2 and 4 */ for (int ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2 "); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4 "); smr_dump(smr,nch); break; case 7: fprintf(stdout,"Frame: %i\n",frameNum); /* Dump the SMRs for all models */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1"); smr_dump(smr, nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3"); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2"); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; case 8: /* Compare 0 and 4 */ psycho_n1 (smr, nch); fprintf(stdout,"0"); smr_dump(smr,nch); for (int ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", model); exit (0); } if (glopts.quickmode == TRUE) { /* copy the smr values and reuse them later */ for (int ch = 0; ch < nch; ch++) { for (int sb = 0; sb < SBLIMIT; sb++) smrdef[ch][sb] = smr[ch][sb]; } } if (glopts.verbosity > 4) { smr_dump(smr, nch); } } #ifdef NEWENCODE sf_transmission_pattern (scalar, scfsi, &frame); main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts); //main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) { CRC_calc (&frame, bit_alloc, scfsi, &crc); } write_header (&frame, &bs); //encode_info (&frame, &bs); if (error_protection) { putbits (&bs, crc, 16); } write_bit_alloc (bit_alloc, &frame, &bs); //encode_bit_alloc (bit_alloc, &frame, &bs); write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs); //encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization_new (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); //subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, // *subband, &frame); write_samples_new(*subband, bit_alloc, &frame, &bs); //sample_encoding (*subband, bit_alloc, &frame, &bs); #else transmission_pattern (scalar, scfsi, &frame); main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) { CRC_calc (&frame, bit_alloc, scfsi, &crc); } encode_info (&frame, &bs); if (error_protection) { encode_CRC (crc, &bs); } encode_bit_alloc (bit_alloc, &frame, &bs); encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); sample_encoding (*subband, bit_alloc, &frame, &bs); #endif /* If not all the bits were used, write out a stack of zeros */ for (int i = 0; i < adb; i++) { put1bit (&bs, 0); } if (xpad_len) { assert(xpad_len > 2); // insert available X-PAD for (int i = header.dab_length - xpad_len; i < header.dab_length - FPAD_LENGTH; i++) { putbits (&bs, xpad_data[i], 8); } } for (int i = header.dab_extension - 1; i >= 0; i--) { CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i); /* this crc is for the previous frame in DAB mode */ if (bs.buf_byte_idx + lg_frame < bs.buf_size) bs.buf[bs.buf_byte_idx + lg_frame] = crc; /* reserved 2 bytes for F-PAD in DAB mode */ putbits (&bs, crc, 8); } if (xpad_len) { /* The F-PAD is also given us by mot-encoder */ putbits (&bs, xpad_data[header.dab_length - 2], 8); putbits (&bs, xpad_data[header.dab_length - 1], 8); } else { putbits (&bs, 0, 16); // FPAD is all-zero } return bs.output_buffer_written; }
int main (int argc, char **argv) { typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT]; SBS *sb_sample; typedef double JSBS[3][SCALE_BLOCK][SBLIMIT]; JSBS *j_sample; typedef double IN[2][HAN_SIZE]; IN *win_que; typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT]; SUB *subband; frame_info frame; frame_header header; char original_file_name[MAX_NAME_SIZE]; char encoded_file_name[MAX_NAME_SIZE]; short **win_buf; static short buffer[2][1152]; static unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT]; static unsigned int scalar[2][3][SBLIMIT], j_scale[3][SBLIMIT]; static double smr[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT]; // FLOAT snr32[32]; short sam[2][1344]; /* was [1056]; */ int model, nch, error_protection; static unsigned int crc; int sb, ch, adb; unsigned long frameBits, sentBits = 0; unsigned long num_samples; int lg_frame; int i; /* Used to keep the SNR values for the fast/quick psy models */ static FLOAT smrdef[2][32]; static int psycount = 0; extern int minimum; sb_sample = (SBS *) mem_alloc (sizeof (SBS), "sb_sample"); j_sample = (JSBS *) mem_alloc (sizeof (JSBS), "j_sample"); win_que = (IN *) mem_alloc (sizeof (IN), "Win_que"); subband = (SUB *) mem_alloc (sizeof (SUB), "subband"); win_buf = (short **) mem_alloc (sizeof (short *) * 2, "win_buf"); /* clear buffers */ memset ((char *) buffer, 0, sizeof (buffer)); memset ((char *) bit_alloc, 0, sizeof (bit_alloc)); memset ((char *) scalar, 0, sizeof (scalar)); memset ((char *) j_scale, 0, sizeof (j_scale)); memset ((char *) scfsi, 0, sizeof (scfsi)); memset ((char *) smr, 0, sizeof (smr)); memset ((char *) lgmin, 0, sizeof (lgmin)); memset ((char *) max_sc, 0, sizeof (max_sc)); //memset ((char *) snr32, 0, sizeof (snr32)); memset ((char *) sam, 0, sizeof (sam)); global_init (); header.extension = 0; frame.header = &header; frame.tab_num = -1; /* no table loaded */ frame.alloc = NULL; header.version = MPEG_AUDIO_ID; /* Default: MPEG-1 */ programName = argv[0]; if (argc == 1) /* no command-line args */ short_usage (); else parse_args (argc, argv, &frame, &model, &num_samples, original_file_name, encoded_file_name); print_config (&frame, &model, original_file_name, encoded_file_name); /* this will load the alloc tables and do some other stuff */ hdr_to_frps (&frame); nch = frame.nch; error_protection = header.error_protection; while (get_audio (musicin, buffer, num_samples, nch, &header) > 0) { if (glopts.verbosity > 1) if (++frameNum % 10 == 0) fprintf (stderr, "[%4u]\r", frameNum); fflush (stderr); win_buf[0] = &buffer[0][0]; win_buf[1] = &buffer[1][0]; adb = available_bits (&header, &glopts); lg_frame = adb / 8; if (header.dab_extension) { /* in 24 kHz we always have 4 bytes */ if (header.sampling_frequency == 1) header.dab_extension = 4; /* You must have one frame in memory if you are in DAB mode */ /* in conformity of the norme ETS 300 401 http://www.etsi.org */ /* see bitstream.c */ if (frameNum == 1) minimum = lg_frame + MINIMUM; adb -= header.dab_extension * 8 + header.dab_length * 8 + 16; } { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*sb_sample)[ch][gr][bl][0] ); } #ifdef REFERENCECODE { /* Old code. left here for reference */ int gr, bl, ch; for (gr = 0; gr < 3; gr++) for (bl = 0; bl < SCALE_BLOCK; bl++) for (ch = 0; ch < nch; ch++) { window_subband (&win_buf[ch], &(*win_que)[ch][0], ch); filter_subband (&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]); } } #endif #ifdef NEWENCODE scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit); find_sf_max (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR_new (*sb_sample, *j_sample, frame.sblimit); scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit); } #else scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit); pick_scale (scalar, &frame, max_sc); if (frame.actual_mode == MPG_MD_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_LR (*sb_sample, *j_sample, frame.sblimit); scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit); } #endif if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smr[ch][sb] = smrdef[ch][sb]; } } else { /* calculate the psymodel */ switch (model) { case -1: psycho_n1 (smr, nch); break; case 0: /* Psy Model A */ psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000); break; case 1: psycho_1 (buffer, max_sc, smr, &frame); break; case 2: for (ch = 0; ch < nch; ch++) { psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 3: /* Modified psy model 1 */ psycho_3 (buffer, max_sc, smr, &frame, &glopts); break; case 4: /* Modified Psycho Model 2 */ for (ch = 0; ch < nch; ch++) { psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); } break; case 5: /* Model 5 comparse model 1 and 3 */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1 "); smr_dump(smr,nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3 "); smr_dump(smr,nch); break; case 6: /* Model 6 compares model 2 and 4 */ for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2 "); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4 "); smr_dump(smr,nch); break; case 7: fprintf(stdout,"Frame: %i\n",frameNum); /* Dump the SMRs for all models */ psycho_1 (buffer, max_sc, smr, &frame); fprintf(stdout,"1"); smr_dump(smr, nch); psycho_3 (buffer, max_sc, smr, &frame, &glopts); fprintf(stdout,"3"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"2"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; case 8: /* Compare 0 and 4 */ psycho_n1 (smr, nch); fprintf(stdout,"0"); smr_dump(smr,nch); for (ch = 0; ch < nch; ch++) psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000, &glopts); fprintf(stdout,"4"); smr_dump(smr,nch); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", model); exit (0); } if (glopts.quickmode == TRUE) /* copy the smr values and reuse them later */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) smrdef[ch][sb] = smr[ch][sb]; } if (glopts.verbosity > 4) smr_dump(smr, nch); } #ifdef NEWENCODE sf_transmission_pattern (scalar, scfsi, &frame); main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts); //main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); write_header (&frame, &bs); //encode_info (&frame, &bs); if (error_protection) putbits (&bs, crc, 16); write_bit_alloc (bit_alloc, &frame, &bs); //encode_bit_alloc (bit_alloc, &frame, &bs); write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs); //encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization_new (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); //subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, // *subband, &frame); write_samples_new(*subband, bit_alloc, &frame, &bs); //sample_encoding (*subband, bit_alloc, &frame, &bs); #else transmission_pattern (scalar, scfsi, &frame); main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); if (error_protection) CRC_calc (&frame, bit_alloc, scfsi, &crc); encode_info (&frame, &bs); if (error_protection) encode_CRC (crc, &bs); encode_bit_alloc (bit_alloc, &frame, &bs); encode_scale (bit_alloc, scfsi, scalar, &frame, &bs); subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc, *subband, &frame); sample_encoding (*subband, bit_alloc, &frame, &bs); #endif /* If not all the bits were used, write out a stack of zeros */ for (i = 0; i < adb; i++) put1bit (&bs, 0); if (header.dab_extension) { /* Reserve some bytes for X-PAD in DAB mode */ putbits (&bs, 0, header.dab_length * 8); for (i = header.dab_extension - 1; i >= 0; i--) { CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i); /* this crc is for the previous frame in DAB mode */ if (bs.buf_byte_idx + lg_frame < bs.buf_size) bs.buf[bs.buf_byte_idx + lg_frame] = crc; /* reserved 2 bytes for F-PAD in DAB mode */ putbits (&bs, crc, 8); } putbits (&bs, 0, 16); } frameBits = sstell (&bs) - sentBits; if (frameBits % 8) { /* a program failure */ fprintf (stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits / 8, frameBits % 8); fprintf (stderr, "If you are reading this, the program is broken\n"); fprintf (stderr, "email [mfc at NOTplanckenerg.com] without the NOT\n"); fprintf (stderr, "with the command line arguments and other info\n"); exit (0); } sentBits += frameBits; } close_bit_stream_w (&bs); if ((glopts.verbosity > 1) && (glopts.vbr == TRUE)) { int i; #ifdef NEWENCODE extern int vbrstats_new[15]; #else extern int vbrstats[15]; #endif fprintf (stdout, "VBR stats:\n"); for (i = 1; i < 15; i++) fprintf (stdout, "%4i ", bitrate[header.version][i]); fprintf (stdout, "\n"); for (i = 1; i < 15; i++) #ifdef NEWENCODE fprintf (stdout,"%4i ",vbrstats_new[i]); #else fprintf (stdout, "%4i ", vbrstats[i]); #endif fprintf (stdout, "\n"); } fprintf (stderr, "Avg slots/frame = %.3f; b/smp = %.2f; bitrate = %.3f kbps\n", (FLOAT) sentBits / (frameNum * 8), (FLOAT) sentBits / (frameNum * 1152), (FLOAT) sentBits / (frameNum * 1152) * s_freq[header.version][header.sampling_frequency]); if (fclose (musicin) != 0) { fprintf (stderr, "Could not close \"%s\".\n", original_file_name); exit (2); } fprintf (stderr, "\nDone\n"); exit (0); }
/* Encode a single frame of audio from 1152 samples Audio samples are taken from glopts->buffer Encoded bit stream is placed in to parameter bs (not intended for use outside the library) Returns the size of the frame or -1 if there is an error */ static int encode_frame(twolame_options *glopts, bit_stream *bs) { int nch = glopts->frame.nch; int sb, ch, adb, i; unsigned long frameBits, initial_bits; short sam[2][1056]; // MEANX int head1,head2; // /MEANX if (!glopts->twolame_init) { fprintf (stderr, "Please call twolame_init_params() before starting encoding.\n"); return -1; } // Scale and mix the input buffer scale_and_mix_samples( glopts ); // Clear the saved audio buffer memset ((char *) sam, 0, sizeof (sam)); /* Store the number of bits initially in the bit buffer */ initial_bits = buffer_sstell(bs); adb = available_bits ( glopts ); /* allow the user to reserve some space at the end of the frame This will however leave fewer bits for the audio. Need to do a sanity check here to see that there are *some* bits left. */ if (glopts->num_ancillary_bits > 0.6*adb) { /* Trying to reserve more than 60% of the frame. 0.6 is arbitrary. but since most applications probably only want to reserve a few bytes, this seems fine. Typical frame size is about 800bytes */ fprintf(stderr,"You're trying to reserve more than 60%% of the mpeg frame for ancillary data\n"); fprintf(stderr,"This is probably an error. But I'll keep going anyway...\n"); } adb -= glopts->num_ancillary_bits; /* MFC 26 July 2003 Doing DAB became a bit harder in the reorganisation of the code. Now there is no guarantee that there is more than one frame in the bitbuffer. But DAB requires that the CRC for the *current* frame be written at the end of the *previous* frame. Workaround: Users (Nicholas?) wanting to implement DAB will have to do some work in the frontend. First: Reserve some bits for yourself (options->num_ancillary_bits) Second: Put the encoder into "single frame mode" i.e. only read 1152 samples per channel. (frontendoptions->singleFrameMode) Third: When you receive each mp2 frame back from the library, you'll have to insert the options->dabCrc[i] values into the end of the frame yourself. (DAB crc calc is done below) The frontend will have to keep the previous frame in memory. As of 26July all that needs to be done is for the frontend to buffer one frame in memory, such that the CRC for the next frame can be written in at the end of it. */ { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for( gr = 0; gr < 3; gr++ ) for ( bl = 0; bl < 12; bl++ ) for ( ch = 0; ch < nch; ch++ ) window_filter_subband( &glopts->smem, &glopts->buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*glopts->sb_sample)[ch][gr][bl][0] ); } scalefactor_calc(*glopts->sb_sample, glopts->scalar, nch, glopts->frame.sblimit); find_sf_max (glopts, glopts->scalar, glopts->max_sc); if (glopts->frame.actual_mode == TWOLAME_JOINT_STEREO) { /* this way we calculate more mono than we need */ /* but it is cheap */ combine_lr (*glopts->sb_sample, *glopts->j_sample, glopts->frame.sblimit); scalefactor_calc (glopts->j_sample, &glopts->j_scale, 1, glopts->frame.sblimit); } if ((glopts->quickmode == TRUE) && (++glopts->psycount % glopts->quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) { glopts->smr[ch][sb] = glopts->smrdef[ch][sb]; } } } else { /* calculate the psymodel */ switch (glopts->psymodel) { case -1: psycho_n1 (glopts, glopts->smr, nch); break; case 0: /* Psy Model A */ psycho_0 (glopts, glopts->smr, glopts->scalar); break; case 1: psycho_1 (glopts, glopts->buffer, glopts->max_sc, glopts->smr); break; case 2: psycho_2 (glopts, glopts->buffer, sam, glopts->smr ); break; case 3: /* Modified psy model 1 */ psycho_3 (glopts, glopts->buffer, glopts->max_sc, glopts->smr); break; case 4: psycho_4 (glopts, glopts->buffer, sam, glopts->smr ); break; default: fprintf (stderr, "Invalid psy model specification: %i\n", glopts->psymodel); return -1; break; } if (glopts->quickmode == TRUE) { /* copy the smr values and reuse them later */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) glopts->smrdef[ch][sb] = glopts->smr[ch][sb]; } } } sf_transmission_pattern (glopts, glopts->scalar, glopts->scfsi); main_bit_allocation (glopts, glopts->smr, glopts->scfsi, glopts->bit_alloc, &adb); #if 0 //MEANX if (glopts->error_protection) crc_calc (glopts, glopts->bit_alloc, glopts->scfsi, &glopts->crc); #endif write_header (glopts, bs); if (glopts->error_protection) buffer_putbits (bs, glopts->crc, 16); head1=write_bit_alloc (glopts, glopts->bit_alloc, bs); head2=write_scalefactors(glopts, glopts->bit_alloc, glopts->scfsi, glopts->scalar, bs); //MEANX printf("Bits: %d + %d = %d\n",head1,head2,head1+head2); subband_quantization (glopts, glopts->scalar, *glopts->sb_sample, glopts->j_scale, *glopts->j_sample, glopts->bit_alloc, *glopts->subband); write_samples(glopts, *glopts->subband, glopts->bit_alloc, bs); /* If not all the bits were used, write out a stack of zeros */ for (i = 0; i < adb; i++) buffer_put1bit (bs, 0); /* MFC July 03 Write an extra byte for 16/24/32/48 input when padding is on. Something must be going astray with the frame size calcs. This fudge works fine for the moment */ if ((glopts->header.samplerate_idx != 0) && (glopts->padding)) // i.e. not a 44.1 or 22kHz input file buffer_putbits (bs, 0, 8); if (glopts->do_dab) { // Do the CRC calc for DAB stuff if required. // It will be up to the frontend to insert it into the end of the // previous frame. for (i=glopts->dab_crc_len-1; i>=0; i--) { dab_crc_calc (glopts, glopts->bit_alloc, glopts->scfsi, glopts->scalar, &glopts->dab_crc[i], i); } } // Allocate space for the reserved ancillary bits for (i=0; i<glopts->num_ancillary_bits;i++) buffer_put1bit(bs, 0); // Calulate the number of bits in this frame frameBits = buffer_sstell(bs) - initial_bits; if (frameBits % 8) { /* a program failure */ fprintf (stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits/8, frameBits%8); fprintf (stderr, "If you are reading this, the program is broken\n"); fprintf (stderr, "email %s with the command line arguments and other info\n", PACKAGE_BUGREPORT); return -1; } //fprintf(stdout,"Frame size: %li\n\n",frameBits/8); // *** FIXME currently broken njh Sept 04 if (glopts->do_energy_levels) do_energy_levels(glopts, bs); // MEANX: Recompute checksum if (glopts->error_protection) { unsigned char *begin=(initial_bits>>3)+bs->buf; int protectedBits=head1+head2; CRC_writeheader(protectedBits, begin); }
static inline enum bt_btr_status read_basic_string_type_and_call( struct bt_btr *btr, bool begin) { size_t buf_at_bytes; const uint8_t *result; size_t available_bytes; const uint8_t *first_chr; enum bt_btr_status status = BT_BTR_STATUS_OK; if (!at_least_one_bit_left(btr)) { BT_LOGV("Reached end of data: btr-addr=%p", btr); status = BT_BTR_STATUS_EOF; goto end; } assert(buf_at_from_addr(btr) % 8 == 0); available_bytes = BITS_TO_BYTES_FLOOR(available_bits(btr)); buf_at_bytes = BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr)); assert(btr->buf.addr); first_chr = &btr->buf.addr[buf_at_bytes]; result = memchr(first_chr, '\0', available_bytes); if (begin && btr->user.cbs.types.string_begin) { BT_LOGV("Calling user function (string, beginning)."); status = btr->user.cbs.types.string_begin( btr->cur_basic_field_type, btr->user.data); BT_LOGV("User function returned: status=%s", bt_btr_status_string(status)); if (status != BT_BTR_STATUS_OK) { BT_LOGW("User function failed: btr-addr=%p, status=%s", btr, bt_btr_status_string(status)); goto end; } } if (!result) { /* No null character yet */ if (btr->user.cbs.types.string) { BT_LOGV("Calling user function (substring)."); status = btr->user.cbs.types.string( (const char *) first_chr, available_bytes, btr->cur_basic_field_type, btr->user.data); BT_LOGV("User function returned: status=%s", bt_btr_status_string(status)); if (status != BT_BTR_STATUS_OK) { BT_LOGW("User function failed: " "btr-addr=%p, status=%s", btr, bt_btr_status_string(status)); goto end; } } consume_bits(btr, BYTES_TO_BITS(available_bytes)); btr->state = BTR_STATE_READ_BASIC_CONTINUE; status = BT_BTR_STATUS_EOF; } else { /* Found the null character */ size_t result_len = (size_t) (result - first_chr); if (btr->user.cbs.types.string && result_len) { BT_LOGV("Calling user function (substring)."); status = btr->user.cbs.types.string( (const char *) first_chr, result_len, btr->cur_basic_field_type, btr->user.data); BT_LOGV("User function returned: status=%s", bt_btr_status_string(status)); if (status != BT_BTR_STATUS_OK) { BT_LOGW("User function failed: " "btr-addr=%p, status=%s", btr, bt_btr_status_string(status)); goto end; } } if (btr->user.cbs.types.string_end) { BT_LOGV("Calling user function (string, end)."); status = btr->user.cbs.types.string_end( btr->cur_basic_field_type, btr->user.data); BT_LOGV("User function returned: status=%s", bt_btr_status_string(status)); if (status != BT_BTR_STATUS_OK) { BT_LOGW("User function failed: " "btr-addr=%p, status=%s", btr, bt_btr_status_string(status)); goto end; } } consume_bits(btr, BYTES_TO_BITS(result_len + 1)); if (stack_empty(btr->stack)) { /* Root is a basic type */ btr->state = BTR_STATE_DONE; } else { /* Go to next field */ stack_top(btr->stack)->index++; btr->state = BTR_STATE_NEXT_FIELD; btr->last_bo = btr->cur_bo; } } end: return status; }
/* Encode a single frame of audio from 1152 samples Audio samples are taken from glopts->buffer Encoded bit stream is placed in to parameter bs (not intended for use outside the library) Returns the size of the frame or -1 if there is an error */ static int encode_frame(twolame_options * glopts, bit_stream * bs) { int nch = glopts->num_channels_out; int sb, ch, adb, i; unsigned long frameBits, initial_bits; short sam[2][1056]; if (!glopts->twolame_init) { fprintf(stderr, "Please call twolame_init_params() before starting encoding.\n"); return -1; } // Scale and mix the input buffer scale_and_mix_samples(glopts); // Clear the saved audio buffer memset((char *) sam, 0, sizeof(sam)); // Number of bits to calculate CRC on glopts->num_crc_bits = 0; // Store the number of bits initially in the bit buffer initial_bits = buffer_sstell(bs); adb = available_bits(glopts); /* allow the user to reserve some space at the end of the frame This will however leave fewer bits for the audio. Need to do a sanity check here to see that there are *some* bits left. */ if (glopts->num_ancillary_bits > 0.6 * adb) { /* Trying to reserve more than 60% of the frame. 0.6 is arbitrary. but since most applications probably only want to reserve a few bytes, this seems fine. Typical frame size is about 800bytes */ fprintf(stderr, "You're trying to reserve more than 60%% of the mpeg frame for ancillary data\n"); fprintf(stderr, "This is probably an error. But I'll keep going anyway...\n"); } adb -= glopts->num_ancillary_bits; /* The DAB scf-crc calc is done below. The frontend will have to keep the previous frame in memory. As of 09May 2014 all that needs to be done is for the frontend to buffer one frame in memory and call twolame_set_DAB_scf_crc */ { int gr, bl, ch; /* New polyphase filter Combines windowing and filtering. Ricardo Feb'03 */ for (gr = 0; gr < 3; gr++) for (bl = 0; bl < 12; bl++) for (ch = 0; ch < nch; ch++) window_filter_subband(&glopts->smem, &glopts->buffer[ch][gr * 12 * 32 + 32 * bl], ch, &(*glopts->sb_sample)[ch][gr][bl][0]); } scalefactor_calc(*glopts->sb_sample, glopts->scalar, nch, glopts->sblimit); find_sf_max(glopts, glopts->scalar, glopts->max_sc); if (glopts->mode == TWOLAME_JOINT_STEREO) { // this way we calculate more mono than we need but it is cheap combine_lr(*glopts->sb_sample, *glopts->j_sample, glopts->sblimit); scalefactor_calc(glopts->j_sample, &glopts->j_scale, 1, glopts->sblimit); } if ((glopts->quickmode == TRUE) && (++glopts->psycount % glopts->quickcount != 0)) { /* We're using quick mode, so we're only calculating the model every 'quickcount' frames. Otherwise, just copy the old ones across */ for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) { glopts->smr[ch][sb] = glopts->smrdef[ch][sb]; } } } else { // calculate the psymodel switch (glopts->psymodel) { case -1: psycho_n1(glopts, glopts->smr, nch); break; case 0: // Psy Model A psycho_0(glopts, glopts->smr, glopts->scalar); break; case 1: psycho_1(glopts, glopts->buffer, glopts->max_sc, glopts->smr); break; case 2: psycho_2(glopts, glopts->buffer, sam, glopts->smr); break; case 3: // Modified psy model 1 psycho_3(glopts, glopts->buffer, glopts->max_sc, glopts->smr); break; case 4: // Modified psy model 2 psycho_4(glopts, glopts->buffer, sam, glopts->smr); break; default: fprintf(stderr, "Invalid psy model specification: %i\n", glopts->psymodel); return -1; break; } if (glopts->quickmode == TRUE) { // copy the smr values and reuse them later for (ch = 0; ch < nch; ch++) { for (sb = 0; sb < SBLIMIT; sb++) glopts->smrdef[ch][sb] = glopts->smr[ch][sb]; } } } sf_transmission_pattern(glopts, glopts->scalar, glopts->scfsi); main_bit_allocation(glopts, glopts->smr, glopts->scfsi, glopts->bit_alloc, &adb); write_header(glopts, bs); // Leave space for 2 bytes of CRC to be filled in later if (glopts->error_protection) buffer_putbits(bs, 0, 16); write_bit_alloc(glopts, glopts->bit_alloc, bs); write_scalefactors(glopts, glopts->bit_alloc, glopts->scfsi, glopts->scalar, bs); subband_quantization(glopts, glopts->scalar, *glopts->sb_sample, glopts->j_scale, *glopts->j_sample, glopts->bit_alloc, *glopts->subband); write_samples(glopts, *glopts->subband, glopts->bit_alloc, bs); // If not all the bits were used, write out a stack of zeros for (i = 0; i < adb; i++) buffer_put1bit(bs, 0); /* MFC July 03 FIXME Write an extra byte for 16/24/32/48 input when padding is on. Something must be going astray with the frame size calcs. This fudge works fine for the moment */ if ((glopts->header.samplerate_idx != 0) && (glopts->padding)) // i.e. not a 44.1 or 22kHz // input file buffer_putbits(bs, 0, 8); if (glopts->do_dab) { // Do the CRC calc for DAB stuff if required. // It will be up to the frontend to insert it into the end of the // previous frame. for (i = glopts->dab_crc_len - 1; i >= 0; i--) { dab_crc_calc(glopts, glopts->bit_alloc, glopts->scfsi, glopts->scalar, &glopts->dab_crc[i], i); } } // Allocate space for the reserved ancillary bits for (i = 0; i < glopts->num_ancillary_bits; i++) buffer_put1bit(bs, 0); // Calulate the number of bits in this frame frameBits = buffer_sstell(bs) - initial_bits; if (frameBits % 8) { /* a program failure */ fprintf(stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits, frameBits / 8, frameBits % 8); fprintf(stderr, "If you are reading this, the program is broken\n"); fprintf(stderr, "email %s with the command line arguments and other info\n", PACKAGE_BUGREPORT); return -1; } // Store the energy levels at the end of the frame if (glopts->do_energy_levels) do_energy_levels(glopts, bs); // MEANX: Recompute checksum from bitstream if (glopts->error_protection) { unsigned char *frame_ptr = bs->buf + (initial_bits >> 3); crc_writeheader(frame_ptr, glopts->num_crc_bits); }
static inline enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr, read_basic_and_call_cb_t read_basic_and_call_cb) { size_t available; int64_t field_size; enum bt_byte_order bo; enum bt_btr_status status = BT_BTR_STATUS_OK; if (!at_least_one_bit_left(btr)) { BT_LOGV("Reached end of data: btr-addr=%p", btr); status = BT_BTR_STATUS_EOF; goto end; } field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); if (field_size < 1) { BT_LOGW("Cannot get basic field type's size: " "btr-addr=%p, ft-addr=%p", btr, btr->cur_basic_field_type); status = BT_BTR_STATUS_ERROR; goto end; } bo = bt_field_type_get_byte_order(btr->cur_basic_field_type); status = validate_contiguous_bo(btr, bo); if (status != BT_BTR_STATUS_OK) { /* validate_contiguous_bo() logs errors */ goto end; } available = available_bits(btr); if (field_size <= available) { /* We have all the bits; decode and set now */ assert(btr->buf.addr); status = read_basic_and_call_cb(btr, btr->buf.addr, buf_at_from_addr(btr)); if (status != BT_BTR_STATUS_OK) { BT_LOGW("Cannot read basic field: " "btr-addr=%p, ft-addr=%p, status=%s", btr, btr->cur_basic_field_type, bt_btr_status_string(status)); goto end; } consume_bits(btr, field_size); if (stack_empty(btr->stack)) { /* Root is a basic type */ btr->state = BTR_STATE_DONE; } else { /* Go to next field */ stack_top(btr->stack)->index++; btr->state = BTR_STATE_NEXT_FIELD; btr->last_bo = btr->cur_bo; } goto end; } /* We are here; it means we don't have enough data to decode this */ BT_LOGV_STR("Not enough data to read the next basic field: setting stitch buffer."); stitch_set_from_remaining_buf(btr); btr->state = BTR_STATE_READ_BASIC_CONTINUE; status = BT_BTR_STATUS_EOF; end: return status; }
static inline enum bt_btr_status read_basic_type_and_call_continue(struct bt_btr *btr, read_basic_and_call_cb_t read_basic_and_call_cb) { size_t available; int64_t field_size; int64_t needed_bits; enum bt_btr_status status = BT_BTR_STATUS_OK; if (!at_least_one_bit_left(btr)) { BT_LOGV("Reached end of data: btr-addr=%p", btr); status = BT_BTR_STATUS_EOF; goto end; } field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); if (field_size < 1) { BT_LOGW("Cannot get basic field type's size: " "btr-addr=%p, ft-addr=%p", btr, btr->cur_basic_field_type); status = BT_BTR_STATUS_ERROR; goto end; } available = available_bits(btr); needed_bits = field_size - btr->stitch.at; BT_LOGV("Continuing basic field decoding: " "btr-addr=%p, field-size=%" PRId64 ", needed-size=%" PRId64 ", " "available-size=%zu", btr, field_size, needed_bits, available); if (needed_bits <= available) { /* We have all the bits; append to stitch, then decode */ stitch_append_from_buf(btr, needed_bits); status = read_basic_and_call_cb(btr, btr->stitch.buf, btr->stitch.offset); if (status != BT_BTR_STATUS_OK) { BT_LOGW("Cannot read basic field: " "btr-addr=%p, ft-addr=%p, status=%s", btr, btr->cur_basic_field_type, bt_btr_status_string(status)); goto end; } if (stack_empty(btr->stack)) { /* Root is a basic type */ btr->state = BTR_STATE_DONE; } else { /* Go to next field */ stack_top(btr->stack)->index++; btr->state = BTR_STATE_NEXT_FIELD; btr->last_bo = btr->cur_bo; } goto end; } /* We are here; it means we don't have enough data to decode this */ BT_LOGV_STR("Not enough data to read the next basic field: appending to stitch buffer."); stitch_append_from_remaining_buf(btr); status = BT_BTR_STATUS_EOF; end: return status; }
static void stitch_append_from_remaining_buf(struct bt_btr *btr) { stitch_append_from_buf(btr, available_bits(btr)); }
static inline bool has_enough_bits(struct bt_btr *btr, size_t sz) { return available_bits(btr) >= sz; }
static inline enum bt_btr_status align_type_state(struct bt_btr *btr, struct bt_field_type *field_type, enum btr_state next_state) { int field_alignment; size_t skip_bits; enum bt_btr_status status = BT_BTR_STATUS_OK; /* Get field's alignment */ field_alignment = bt_field_type_get_alignment(field_type); if (field_alignment < 0) { BT_LOGW("Cannot get field type's alignment: " "btr-addr=%p, ft-addr=%p, ft-id=%s", btr, field_type, bt_field_type_id_string( bt_field_type_get_type_id(field_type))); status = BT_BTR_STATUS_ERROR; goto end; } /* * 0 means "undefined" for variants; what we really want is 1 * (always aligned) */ if (field_alignment == 0) { field_alignment = 1; } /* Compute how many bits we need to skip */ skip_bits = bits_to_skip_to_align_to(btr, field_alignment); /* Nothing to skip? aligned */ if (skip_bits == 0) { btr->state = next_state; goto end; } /* Make sure there's at least one bit left */ if (!at_least_one_bit_left(btr)) { status = BT_BTR_STATUS_EOF; goto end; } /* Consume as many bits as possible in what's left */ consume_bits(btr, MIN(available_bits(btr), skip_bits)); /* Are we done now? */ skip_bits = bits_to_skip_to_align_to(btr, field_alignment); if (skip_bits == 0) { /* Yes: go to next state */ btr->state = next_state; goto end; } else { /* No: need more data */ BT_LOGV("Reached end of data when aligning: btr-addr=%p", btr); status = BT_BTR_STATUS_EOF; } end: return status; }