Example #1
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->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 = twolame_buffer_sstell(bs);

    adb = twolame_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++)
                    twolame_window_filter_subband(&glopts->smem,
                                                  &glopts->buffer[ch][gr * 12 * 32 + 32 * bl], ch,
                                                  &(*glopts->sb_sample)[ch][gr][bl][0]);
    }

    twolame_scalefactor_calc(*glopts->sb_sample, glopts->scalar, nch, glopts->sblimit);
    twolame_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
        twolame_combine_lr(*glopts->sb_sample, *glopts->j_sample, glopts->sblimit);
        twolame_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:
            twolame_psycho_n1(glopts, glopts->smr, nch);
            break;
        case 0:                // Psy Model A
            twolame_psycho_0(glopts, glopts->smr, glopts->scalar);
            break;
        case 1:
            twolame_psycho_1(glopts, glopts->buffer, glopts->max_sc, glopts->smr);
            break;
        case 2:
            twolame_psycho_2(glopts, glopts->buffer, sam, glopts->smr);
            break;
        case 3:
            // Modified psy model 1
            twolame_psycho_3(glopts, glopts->buffer, glopts->max_sc, glopts->smr);
            break;
        case 4:
            // Modified psy model 2
            twolame_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];
            }
        }
    }


    twolame_sf_transmission_pattern(glopts, glopts->scalar, glopts->scfsi);
    twolame_main_bit_allocation(glopts, glopts->smr, glopts->scfsi, glopts->bit_alloc, &adb);

    twolame_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);

    twolame_write_bit_alloc(glopts, glopts->bit_alloc, bs);
    twolame_write_scalefactors(glopts, glopts->bit_alloc, glopts->scfsi, glopts->scalar, bs);

    twolame_subband_quantization(glopts, glopts->scalar, *glopts->sb_sample, glopts->j_scale,
                                 *glopts->j_sample, glopts->bit_alloc, *glopts->subband);
    twolame_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);


    /* pad the current frame when needed */
    if (glopts->header.padding)
        // 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--) {
            twolame_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 = twolame_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)
        twolame_do_energy_levels(glopts, bs);

    // MEANX: Recompute checksum from bitstream
    if (glopts->error_protection) {
        unsigned char *frame_ptr = bs->buf + (initial_bits >> 3);
        twolame_crc_writeheader(frame_ptr, glopts->num_crc_bits);
    }
Example #2
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);
  }