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; #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 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); }
/* 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); }