mirror of
				https://github.com/cookiengineer/audacity
				synced 2025-10-31 22:23:54 +01:00 
			
		
		
		
	... cast enum to int before testing for negative value which is not in the enumeration but signifies "undefined"
		
			
				
	
	
		
			935 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			935 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *	TwoLAME: an optimized MPEG Audio Layer Two encoder
 | |
|  *
 | |
|  *	Copyright (C) 2001-2004 Michael Cheng
 | |
|  *	Copyright (C) 2004-2006 The TwoLAME Project
 | |
|  *
 | |
|  *	This library is free software; you can redistribute it and/or
 | |
|  *	modify it under the terms of the GNU Lesser General Public
 | |
|  *	License as published by the Free Software Foundation; either
 | |
|  *	version 2.1 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  *	This library is distributed in the hope that it will be useful,
 | |
|  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  *	Lesser General Public License for more details.
 | |
|  *
 | |
|  *	You should have received a copy of the GNU Lesser General Public
 | |
|  *	License along with this library; if not, write to the Free Software
 | |
|  *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
|  *
 | |
|  *  $Id$
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <math.h>
 | |
| #include <assert.h>
 | |
| #include <limits.h>
 | |
| 
 | |
| #include "twolame.h"
 | |
| #include "common.h"
 | |
| #include "bitbuffer.h"
 | |
| #include "mem.h"
 | |
| #include "crc.h"
 | |
| #include "dab.h"
 | |
| #include "psycho_n1.h"
 | |
| #include "psycho_0.h"
 | |
| #include "psycho_1.h"
 | |
| #include "psycho_2.h"
 | |
| #include "psycho_3.h"
 | |
| #include "psycho_4.h"
 | |
| #include "availbits.h"
 | |
| #include "subband.h"
 | |
| #include "encode.h"
 | |
| #include "energy.h"
 | |
| #include "util.h"
 | |
| 
 | |
| #include "bitbuffer_inline.h"
 | |
| 
 | |
| 
 | |
| /*
 | |
|   twolame_init
 | |
|   Create a set of encoding options and return a pointer to this structure
 | |
|   
 | |
|   Returns NULL if unsuccessful (can't allocate memory)
 | |
|   Otherwise returns pointer to memory block
 | |
| */
 | |
| twolame_options *twolame_init(void)
 | |
| {
 | |
|     twolame_options *newoptions = NULL;
 | |
| 
 | |
|     newoptions = (twolame_options *) TWOLAME_MALLOC(sizeof(twolame_options));
 | |
|     if (newoptions == NULL) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     newoptions->version = -1;
 | |
|     newoptions->num_channels_in = 0;
 | |
|     newoptions->num_channels_out = 0;
 | |
|     newoptions->samplerate_in = 0;
 | |
|     newoptions->samplerate_out = 0;
 | |
| 
 | |
|     newoptions->mode = TWOLAME_AUTO_MODE;   // Choose a proper mode later
 | |
|     newoptions->psymodel = 3;
 | |
|     newoptions->bitrate = -1;   // Default bitrate is set in init_params
 | |
|     newoptions->vbr = FALSE;
 | |
|     newoptions->vbrlevel = 5.0;
 | |
|     newoptions->athlevel = 0.0;
 | |
| 
 | |
|     newoptions->quickmode = FALSE;
 | |
|     newoptions->quickcount = 10;
 | |
|     newoptions->emphasis = TWOLAME_EMPHASIS_N;
 | |
|     newoptions->private_bit = 0;
 | |
|     newoptions->copyright = FALSE;
 | |
|     newoptions->original = TRUE;
 | |
|     newoptions->error_protection = FALSE;
 | |
|     newoptions->padding = TWOLAME_PAD_NO;
 | |
|     newoptions->do_dab = FALSE;
 | |
|     newoptions->dab_crc_len = 2;
 | |
|     newoptions->dab_xpad_len = 0;
 | |
|     newoptions->verbosity = 2;
 | |
|     newoptions->vbr_upper_index = 0;
 | |
| 
 | |
|     newoptions->scale = 1.0;    // scaling disabled
 | |
|     newoptions->scale_left = 1.0;   // scaling disabled
 | |
|     newoptions->scale_right = 1.0;  // scaling disabled
 | |
| 
 | |
|     newoptions->do_energy_levels = FALSE;
 | |
|     newoptions->num_ancillary_bits = -1;
 | |
| 
 | |
| 
 | |
|     newoptions->vbr_frame_count = 0;    // only used for debugging
 | |
|     newoptions->tablenum = 0;
 | |
| 
 | |
|     newoptions->twolame_init = 0;
 | |
|     newoptions->subband = NULL;
 | |
|     newoptions->j_sample = NULL;
 | |
|     newoptions->sb_sample = NULL;
 | |
|     newoptions->psycount = 0;
 | |
| 
 | |
|     newoptions->p0mem = NULL;
 | |
|     newoptions->p1mem = NULL;
 | |
|     newoptions->p2mem = NULL;
 | |
|     newoptions->p3mem = NULL;
 | |
|     newoptions->p4mem = NULL;
 | |
| 
 | |
|     memset(newoptions->vbrstats, 0, sizeof(newoptions->vbrstats));
 | |
| 
 | |
|     return (newoptions);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // Returns 0 if successful
 | |
| // Returns -1 if unsuccessful
 | |
| static int init_header_info(twolame_options * glopts)
 | |
| {
 | |
|     frame_header *header = &glopts->header;
 | |
| 
 | |
|     /* use the options to create header info structure */
 | |
|     header->lay = 2;
 | |
|     header->error_protection = glopts->error_protection;
 | |
|     header->version = glopts->version;
 | |
| 
 | |
|     // Convert the sampling frequency to the required index
 | |
|     header->samplerate_idx = twolame_get_samplerate_index(glopts->samplerate_out);
 | |
|     if (header->samplerate_idx < 0) {
 | |
|         fprintf(stderr, "Not a valid samplerate: %i\n", glopts->samplerate_out);
 | |
|         return -1;
 | |
|     }
 | |
|     // Convert the bitrate to the an index 
 | |
|     header->bitrate_index = twolame_get_bitrate_index(glopts->bitrate, header->version);
 | |
|     if (header->bitrate_index < 0) {
 | |
|         fprintf(stderr, "Not a valid bitrate (%i) for MPEG version '%s'\n", glopts->bitrate,
 | |
|                 twolame_mpeg_version_name(glopts->version));
 | |
|         return -1;
 | |
|     }
 | |
|     // Convert the max VBR bitrate to the an index 
 | |
|     glopts->vbr_upper_index = twolame_get_bitrate_index(glopts->vbr_max_bitrate, header->version);
 | |
|     if (glopts->vbr_upper_index < 0) {
 | |
|         fprintf(stderr, "Not a valid max VBR bitrate for this version: %i\n",
 | |
|                 glopts->vbr_max_bitrate);
 | |
|         return -1;
 | |
|     }
 | |
|     // Copy accross the other settings 
 | |
|     header->padding = glopts->padding;
 | |
|     header->private_bit = glopts->private_bit;
 | |
|     header->mode = glopts->mode;
 | |
|     header->mode_ext = 0;
 | |
|     header->copyright = glopts->copyright;
 | |
|     header->original = glopts->original;
 | |
|     header->emphasis = glopts->emphasis;
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * This function should actually *check* the parameters to see if they
 | |
|  * make sense. 
 | |
|  */
 | |
| 
 | |
| int twolame_init_params(twolame_options * glopts)
 | |
| {
 | |
| 
 | |
|     if (glopts->twolame_init) {
 | |
|         fprintf(stderr, "Already called twolame_init_params() once.\n");
 | |
|         return 1;
 | |
|     }
 | |
|     // Check the number of channels
 | |
|     if (glopts->num_channels_in != 1 && glopts->num_channels_in != 2) {
 | |
|         fprintf(stderr,
 | |
|                 "twolame_init_params(): must specify number of input channels using twolame_set_num_channels().\n");
 | |
|         return -1;
 | |
|     }
 | |
|     // If not output samplerate has been set, then set it to the input sample rate
 | |
|     if (glopts->samplerate_out < 1) {
 | |
|         glopts->samplerate_out = glopts->samplerate_in;
 | |
|     }
 | |
|     // If the MPEG version has not been set, then choose automatically
 | |
|     if ((int)glopts->version == -1) {
 | |
|         // Get the MPEG version for the chosen samplerate
 | |
|         glopts->version = twolame_get_version_for_samplerate(glopts->samplerate_out);
 | |
|         if ((int)glopts->version < 0) {
 | |
|             fprintf(stderr, "twolame_init_params(): invalid samplerate: %i\n",
 | |
|                     glopts->samplerate_out);
 | |
|             return -1;
 | |
|         } else if (glopts->verbosity >= 3) {
 | |
|             fprintf(stderr, "Chosen version '%s' for samplerate of %d Hz.\n",
 | |
|                     twolame_mpeg_version_name(glopts->version), glopts->samplerate_out);
 | |
|         }
 | |
|     }
 | |
|     // Choose mode (if none chosen)
 | |
|     if (glopts->mode == TWOLAME_AUTO_MODE) {
 | |
|         if (glopts->num_channels_in == 2)
 | |
|             glopts->mode = TWOLAME_STEREO;
 | |
|         else
 | |
|             glopts->mode = TWOLAME_MONO;
 | |
|         if (glopts->verbosity >= 3) {
 | |
|             fprintf(stderr, "Chosen mode to be '%s' because of %d input channels.\n",
 | |
|                     twolame_get_mode_name(glopts), glopts->num_channels_in);
 | |
|         }
 | |
|     }
 | |
|     // Choose the bitrate (if none chosen)
 | |
|     if (glopts->bitrate <= 0) {
 | |
|         if (glopts->mode == TWOLAME_MONO) {
 | |
|             switch (glopts->samplerate_out) {
 | |
|             case 48000:
 | |
|                 glopts->bitrate = 96;
 | |
|                 break;          // (LAME=64)
 | |
|             case 44100:
 | |
|                 glopts->bitrate = 96;
 | |
|                 break;          // (LAME=64)
 | |
|             case 32000:
 | |
|                 glopts->bitrate = 80;
 | |
|                 break;          // (LAME=48)
 | |
|             case 24000:
 | |
|                 glopts->bitrate = 48;
 | |
|                 break;          // (LAME=32)
 | |
|             case 22050:
 | |
|                 glopts->bitrate = 48;
 | |
|                 break;          // (LAME=32)
 | |
|             case 16000:
 | |
|                 glopts->bitrate = 32;
 | |
|                 break;          // (LAME=24)
 | |
|             }
 | |
|         } else {
 | |
|             switch (glopts->samplerate_out) {
 | |
|             case 48000:
 | |
|                 glopts->bitrate = 192;
 | |
|                 break;          // (LAME=128)
 | |
|             case 44100:
 | |
|                 glopts->bitrate = 192;
 | |
|                 break;          // (LAME=128)
 | |
|             case 32000:
 | |
|                 glopts->bitrate = 160;
 | |
|                 break;          // (LAME=96)
 | |
|             case 24000:
 | |
|                 glopts->bitrate = 96;
 | |
|                 break;          // (LAME=64)
 | |
|             case 22050:
 | |
|                 glopts->bitrate = 96;
 | |
|                 break;          // (LAME=64)
 | |
|             case 16000:
 | |
|                 glopts->bitrate = 64;
 | |
|                 break;          // (LAME=48)
 | |
|             }
 | |
|         }
 | |
|         if (glopts->verbosity >= 3) {
 | |
|             fprintf(stderr, "Chosen bitrate of %dkbps for samplerate of %d Hz.\n",
 | |
|                     glopts->bitrate, glopts->samplerate_out);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* Can't do DAB and energylevel extensions at the same time Because both of them think they're
 | |
|        the only ones inserting information into the ancillary section of the frame */
 | |
|     if (glopts->do_dab && glopts->do_energy_levels) {
 | |
|         fprintf(stderr, "Error: Can't do DAB and Energy Levels at the same time\n");
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     /* Set the number of ancillary bits automatically, if none set */
 | |
|     if (glopts->num_ancillary_bits < 0) {
 | |
|         if (glopts->do_energy_levels) {
 | |
|             glopts->num_ancillary_bits = get_required_energy_bits(glopts);
 | |
|         } else {
 | |
|             glopts->num_ancillary_bits = 0;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* Check that if we're doing energy levels, that there's enough space to put the information */
 | |
|     if (glopts->do_energy_levels) {
 | |
|         int required = get_required_energy_bits(glopts);
 | |
|         if (glopts->num_ancillary_bits < required) {
 | |
|             fprintf(stderr, "Warning: Too few ancillary bits to store energy levels: %i<%i\n",
 | |
|                     glopts->num_ancillary_bits, required);
 | |
|             return -1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* 
 | |
|      * MFC Feb 2003: in VBR mode, joint
 | |
|      * stereo doesn't make any sense at
 | |
|      * the moment, as there are no noisy
 | |
|      * subbands according to
 | |
|      * bits_for_nonoise in vbr mode
 | |
|      */
 | |
|     if (glopts->vbr && glopts->mode == TWOLAME_JOINT_STEREO) {
 | |
|         fprintf(stderr, "Warning: Can't do Joint Stereo with VBR, switching to normal stereo.\n");
 | |
| 
 | |
|         // force stereo mode
 | |
|         twolame_set_mode(glopts, TWOLAME_STEREO);
 | |
|     }
 | |
| 
 | |
|     /* Can't do padding and VBR at same time */
 | |
|     if (glopts->vbr && glopts->padding == TRUE) {
 | |
|         fprintf(stderr, "Error: Can't do padding and VBR at same time\n");
 | |
|         return -1;
 | |
|     }
 | |
|     // Set the Number of output channels
 | |
|     glopts->num_channels_out = (glopts->mode == TWOLAME_MONO) ? 1 : 2;
 | |
| 
 | |
| 
 | |
| 
 | |
|     // build mpeg header from parameters
 | |
|     if (init_header_info(glopts) < 0) {
 | |
|         return -1;
 | |
|     }
 | |
|     // Select table number and sblimit
 | |
|     if (encode_init(glopts) < 0) {
 | |
|         return -1;
 | |
|     }
 | |
|     // initialise bitrate allocation
 | |
|     if (init_bit_allocation(glopts) < 0) {
 | |
|         return -1;
 | |
|     }
 | |
|     // Check input samplerate is same as output samplerate
 | |
|     if (glopts->samplerate_out != glopts->samplerate_in) {
 | |
|         fprintf(stderr,
 | |
|                 "twolame_init_params(): sorry, twolame doesn't support resampling (yet).\n");
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     // Initialise interal variables
 | |
|     glopts->samples_in_buffer = 0;
 | |
|     glopts->psycount = 0;
 | |
| 
 | |
| 
 | |
|     // Allocate memory to larger buffers 
 | |
|     glopts->subband = (subband_t *) TWOLAME_MALLOC(sizeof(subband_t));
 | |
|     glopts->j_sample = (jsb_sample_t *) TWOLAME_MALLOC(sizeof(jsb_sample_t));
 | |
|     glopts->sb_sample = (sb_sample_t *) TWOLAME_MALLOC(sizeof(sb_sample_t));
 | |
| 
 | |
|     // clear buffers
 | |
|     memset((char *) glopts->buffer, 0, sizeof(glopts->buffer));
 | |
|     memset((char *) glopts->bit_alloc, 0, sizeof(glopts->bit_alloc));
 | |
|     memset((char *) glopts->scfsi, 0, sizeof(glopts->scfsi));
 | |
|     memset((char *) glopts->scalar, 0, sizeof(glopts->scalar));
 | |
|     memset((char *) glopts->j_scale, 0, sizeof(glopts->j_scale));
 | |
|     memset((char *) glopts->smrdef, 0, sizeof(glopts->smrdef));
 | |
|     memset((char *) glopts->smr, 0, sizeof(glopts->smr));
 | |
|     memset((char *) glopts->max_sc, 0, sizeof(glopts->max_sc));
 | |
| 
 | |
|     // Initialise subband windowfilter
 | |
|     if (init_subband(&glopts->smem) < 0) {
 | |
|         return -1;
 | |
|     }
 | |
|     // All initalised now :)
 | |
|     glopts->twolame_init++;
 | |
| 
 | |
|     return (0);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Scale the samples in the frame sample buffer
 | |
|    using the user specified values
 | |
|    and downmix/upmix according to the number of input/output channels 
 | |
| */
 | |
| static void scale_and_mix_samples(twolame_options * glopts)
 | |
| {
 | |
|     int num_samples = glopts->samples_in_buffer;
 | |
|     int i;
 | |
| 
 | |
|     // apply scaling to both channels 
 | |
|     if (glopts->scale != 0 && glopts->scale != 1.0) {
 | |
|         for (i = 0; i < num_samples; ++i) {
 | |
|             glopts->buffer[0][i] *= glopts->scale;
 | |
|             if (glopts->num_channels_in == 2)
 | |
|                 glopts->buffer[1][i] *= glopts->scale;
 | |
|         }
 | |
|     }
 | |
|     // apply scaling to channel 0 (left) 
 | |
|     if (glopts->scale_left != 0 && glopts->scale_left != 1.0) {
 | |
|         for (i = 0; i < num_samples; ++i) {
 | |
|             glopts->buffer[0][i] *= glopts->scale_left;
 | |
|         }
 | |
|     }
 | |
|     // apply scaling to channel 1 (right) 
 | |
|     if (glopts->scale_right != 0 && glopts->scale_right != 1.0) {
 | |
|         for (i = 0; i < num_samples; ++i) {
 | |
|             glopts->buffer[1][i] *= glopts->scale_right;
 | |
|         }
 | |
|     }
 | |
|     // Downmix to Mono if 2 channels in and 1 channel out 
 | |
|     if (glopts->num_channels_in == 2 && glopts->num_channels_out == 1) {
 | |
|         for (i = 0; i < num_samples; ++i) {
 | |
|             glopts->buffer[0][i] = ((long) glopts->buffer[0][i] + glopts->buffer[1][i]) / 2;
 | |
|             glopts->buffer[1][i] = 0;
 | |
|         }
 | |
|     }
 | |
|     // Upmix to Stereo if 2 channels out and 1 channel in
 | |
|     if (glopts->num_channels_in == 1 && glopts->num_channels_out == 2) {
 | |
|         for (i = 0; i < num_samples; ++i) {
 | |
|             glopts->buffer[1][i] = glopts->buffer[0][i];
 | |
|         }
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| /*
 | |
| 	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;
 | |
| 
 | |
| 
 | |
|     /* 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->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);
 | |
|     }
 | |
|     // fprintf(stderr,"Frame size: %li\n\n",frameBits/8);
 | |
| 
 | |
|     return frameBits / 8;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|   glopts
 | |
|   leftpcm - holds left channel (or mono channel)
 | |
|   rightpcm - d'uh
 | |
|   num_samples - the number of samples in each channel
 | |
|   mp2buffer - a pointer to the place where we want the mpeg data to be written
 | |
|   mp2buffer_size - how much space the user allocated for this buffer
 | |
|   mp2fill_size - how much mpeg data the library has put into the mp2buffer 
 | |
| */
 | |
| 
 | |
| int twolame_encode_buffer(twolame_options * glopts,
 | |
|                           const short int leftpcm[],
 | |
|                           const short int rightpcm[],
 | |
|                           int num_samples, unsigned char *mp2buffer, int mp2buffer_size)
 | |
| {
 | |
|     int mp2_size = 0;
 | |
|     bit_stream *mybs;
 | |
|     int i;
 | |
| 
 | |
|     if (num_samples == 0)
 | |
|         return 0;
 | |
| 
 | |
| 
 | |
|     // now would be a great time to validate the size of the buffer.
 | |
|     // samples/1152 * sizeof(frame) < mp2buffer_size 
 | |
|     mybs = buffer_init(mp2buffer, mp2buffer_size);
 | |
| 
 | |
| 
 | |
|     // Use up all the samples in in_buffer
 | |
|     while (num_samples) {
 | |
| 
 | |
|         // fill up glopts->buffer with as much as we can
 | |
|         int samples_to_copy = TWOLAME_SAMPLES_PER_FRAME - glopts->samples_in_buffer;
 | |
|         if (num_samples < samples_to_copy)
 | |
|             samples_to_copy = num_samples;
 | |
| 
 | |
|         /* Copy across samples */
 | |
|         for (i = 0; i < samples_to_copy; i++) {
 | |
|             glopts->buffer[0][glopts->samples_in_buffer + i] = *leftpcm++;
 | |
|             if (glopts->num_channels_in == 2)
 | |
|                 glopts->buffer[1][glopts->samples_in_buffer + i] = *rightpcm++;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /* Update sample counts */
 | |
|         glopts->samples_in_buffer += samples_to_copy;
 | |
|         num_samples -= samples_to_copy;
 | |
| 
 | |
| 
 | |
|         // is there enough to encode a whole frame ?
 | |
|         if (glopts->samples_in_buffer >= TWOLAME_SAMPLES_PER_FRAME) {
 | |
|             int bytes = encode_frame(glopts, mybs);
 | |
|             if (bytes <= 0) {
 | |
|                 buffer_deinit(&mybs);
 | |
|                 return bytes;
 | |
|             }
 | |
|             mp2_size += bytes;
 | |
|             glopts->samples_in_buffer -= TWOLAME_SAMPLES_PER_FRAME;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // free up the bit stream buffer structure
 | |
|     buffer_deinit(&mybs);
 | |
| 
 | |
|     return (mp2_size);
 | |
| }
 | |
| 
 | |
| 
 | |
| int twolame_encode_buffer_interleaved(twolame_options * glopts,
 | |
|                                       const short int pcm[],
 | |
|                                       int num_samples, unsigned char *mp2buffer, int mp2buffer_size)
 | |
| {
 | |
|     int mp2_size = 0;
 | |
|     bit_stream *mybs;
 | |
|     int i;
 | |
| 
 | |
|     if (num_samples == 0)
 | |
|         return 0;
 | |
| 
 | |
| 
 | |
|     // now would be a great time to validate the size of the buffer.
 | |
|     // samples/1152 * sizeof(frame) < mp2buffer_size 
 | |
|     mybs = buffer_init(mp2buffer, mp2buffer_size);
 | |
| 
 | |
|     // Use up all the samples in in_buffer
 | |
|     while (num_samples) {
 | |
| 
 | |
|         // fill up glopts->buffer with as much as we can
 | |
|         int samples_to_copy = TWOLAME_SAMPLES_PER_FRAME - glopts->samples_in_buffer;
 | |
|         if (num_samples < samples_to_copy)
 | |
|             samples_to_copy = num_samples;
 | |
| 
 | |
|         /* Copy across samples */
 | |
|         for (i = 0; i < samples_to_copy; i++) {
 | |
|             glopts->buffer[0][glopts->samples_in_buffer + i] = *pcm++;
 | |
|             if (glopts->num_channels_in == 2)
 | |
|                 glopts->buffer[1][glopts->samples_in_buffer + i] = *pcm++;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /* Update sample counts */
 | |
|         glopts->samples_in_buffer += samples_to_copy;
 | |
|         num_samples -= samples_to_copy;
 | |
| 
 | |
| 
 | |
|         // is there enough to encode a whole frame ?
 | |
|         if (glopts->samples_in_buffer >= TWOLAME_SAMPLES_PER_FRAME) {
 | |
|             int bytes = encode_frame(glopts, mybs);
 | |
|             if (bytes <= 0) {
 | |
|                 buffer_deinit(&mybs);
 | |
|                 return bytes;
 | |
|             }
 | |
|             mp2_size += bytes;
 | |
|             glopts->samples_in_buffer -= TWOLAME_SAMPLES_PER_FRAME;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // free up the bit stream buffer structure
 | |
|     buffer_deinit(&mybs);
 | |
| 
 | |
| 
 | |
|     return (mp2_size);
 | |
| }
 | |
| 
 | |
| 
 | |
| static void float32_to_short(const float in[], short out[], int num_samples, int stride)
 | |
| {
 | |
|     int n;
 | |
| 
 | |
|     for (n = 0; n < num_samples; n++) {
 | |
|         int tmp = lrintf(in[n * stride] * 32768.0f);
 | |
|         if (tmp > SHRT_MAX) {
 | |
|             out[n] = SHRT_MAX;
 | |
|         } else if (tmp < SHRT_MIN) {
 | |
|             out[n] = SHRT_MIN;
 | |
|         } else {
 | |
|             out[n] = (short) tmp;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|   glopts
 | |
|   leftpcm - holds left channel (or mono channel)
 | |
|   rightpcm - d'uh
 | |
|   num_samples - the number of samples in each channel
 | |
|   mp2buffer - a pointer to the place where we want the mpeg data to be written
 | |
|   mp2buffer_size - how much space the user allocated for this buffer
 | |
|   mp2fill_size - how much mpeg data the library has put into the mp2buffer 
 | |
| */
 | |
| 
 | |
| int twolame_encode_buffer_float32(twolame_options * glopts,
 | |
|                                   const float leftpcm[],
 | |
|                                   const float rightpcm[],
 | |
|                                   int num_samples, unsigned char *mp2buffer, int mp2buffer_size)
 | |
| {
 | |
|     int mp2_size = 0;
 | |
|     bit_stream *mybs;
 | |
| 
 | |
|     if (num_samples == 0)
 | |
|         return 0;
 | |
| 
 | |
| 
 | |
|     // now would be a great time to validate the size of the buffer.
 | |
|     // samples/1152 * sizeof(frame) < mp2buffer_size 
 | |
|     mybs = buffer_init(mp2buffer, mp2buffer_size);
 | |
| 
 | |
| 
 | |
|     // Use up all the samples in in_buffer
 | |
|     while (num_samples) {
 | |
| 
 | |
|         // fill up glopts->buffer with as much as we can
 | |
|         int samples_to_copy = TWOLAME_SAMPLES_PER_FRAME - glopts->samples_in_buffer;
 | |
|         if (num_samples < samples_to_copy)
 | |
|             samples_to_copy = num_samples;
 | |
| 
 | |
|         /* Copy across samples */
 | |
|         float32_to_short(leftpcm, &glopts->buffer[0][glopts->samples_in_buffer], samples_to_copy,
 | |
|                          1);
 | |
|         if (glopts->num_channels_in == 2)
 | |
|             float32_to_short(rightpcm, &glopts->buffer[1][glopts->samples_in_buffer],
 | |
|                              samples_to_copy, 1);
 | |
|         leftpcm += samples_to_copy;
 | |
|         rightpcm += samples_to_copy;
 | |
| 
 | |
|         /* Update sample counts */
 | |
|         glopts->samples_in_buffer += samples_to_copy;
 | |
|         num_samples -= samples_to_copy;
 | |
| 
 | |
| 
 | |
|         // is there enough to encode a whole frame ?
 | |
|         if (glopts->samples_in_buffer >= TWOLAME_SAMPLES_PER_FRAME) {
 | |
|             int bytes = encode_frame(glopts, mybs);
 | |
|             if (bytes <= 0) {
 | |
|                 buffer_deinit(&mybs);
 | |
|                 return bytes;
 | |
|             }
 | |
|             mp2_size += bytes;
 | |
|             glopts->samples_in_buffer -= TWOLAME_SAMPLES_PER_FRAME;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // free up the bit stream buffer structure
 | |
|     buffer_deinit(&mybs);
 | |
| 
 | |
|     return (mp2_size);
 | |
| }
 | |
| 
 | |
| 
 | |
| int twolame_encode_buffer_float32_interleaved(twolame_options * glopts,
 | |
|                                               const float pcm[],
 | |
|                                               int num_samples,
 | |
|                                               unsigned char *mp2buffer, int mp2buffer_size)
 | |
| {
 | |
|     int mp2_size = 0;
 | |
|     bit_stream *mybs;
 | |
| 
 | |
|     if (num_samples == 0)
 | |
|         return 0;
 | |
| 
 | |
| 
 | |
|     // now would be a great time to validate the size of the buffer.
 | |
|     // samples/1152 * sizeof(frame) < mp2buffer_size 
 | |
|     mybs = buffer_init(mp2buffer, mp2buffer_size);
 | |
| 
 | |
|     // Use up all the samples in in_buffer
 | |
|     while (num_samples) {
 | |
| 
 | |
|         // fill up glopts->buffer with as much as we can
 | |
|         int samples_to_copy = TWOLAME_SAMPLES_PER_FRAME - glopts->samples_in_buffer;
 | |
|         if (num_samples < samples_to_copy)
 | |
|             samples_to_copy = num_samples;
 | |
| 
 | |
|         /* Copy across samples */
 | |
|         float32_to_short(pcm, &glopts->buffer[0][glopts->samples_in_buffer], samples_to_copy,
 | |
|                          glopts->num_channels_in);
 | |
|         if (glopts->num_channels_in == 2)
 | |
|             float32_to_short(pcm + 1, &glopts->buffer[1][glopts->samples_in_buffer],
 | |
|                              samples_to_copy, glopts->num_channels_in);
 | |
|         pcm += (samples_to_copy * glopts->num_channels_in);
 | |
| 
 | |
| 
 | |
|         /* Update sample counts */
 | |
|         glopts->samples_in_buffer += samples_to_copy;
 | |
|         num_samples -= samples_to_copy;
 | |
| 
 | |
| 
 | |
|         // is there enough to encode a whole frame ?
 | |
|         if (glopts->samples_in_buffer >= TWOLAME_SAMPLES_PER_FRAME) {
 | |
|             int bytes = encode_frame(glopts, mybs);
 | |
|             if (bytes <= 0) {
 | |
|                 buffer_deinit(&mybs);
 | |
|                 return bytes;
 | |
|             }
 | |
|             mp2_size += bytes;
 | |
|             glopts->samples_in_buffer -= TWOLAME_SAMPLES_PER_FRAME;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // free up the bit stream buffer structure
 | |
|     buffer_deinit(&mybs);
 | |
| 
 | |
| 
 | |
|     return (mp2_size);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| int twolame_encode_flush(twolame_options * glopts, unsigned char *mp2buffer, int mp2buffer_size)
 | |
| {
 | |
|     bit_stream *mybs = NULL;
 | |
|     int mp2_size = 0;
 | |
|     int i;
 | |
| 
 | |
|     if (glopts->samples_in_buffer == 0) {
 | |
|         // No samples left over
 | |
|         return 0;
 | |
|     }
 | |
|     // Create bit stream structure
 | |
|     mybs = buffer_init(mp2buffer, mp2buffer_size);
 | |
| 
 | |
|     // Pad out the PCM buffers with 0 and encode the frame
 | |
|     for (i = glopts->samples_in_buffer; i < TWOLAME_SAMPLES_PER_FRAME; i++) {
 | |
|         glopts->buffer[0][i] = glopts->buffer[1][i] = 0;
 | |
|     }
 | |
| 
 | |
|     // Encode the frame 
 | |
|     mp2_size = encode_frame(glopts, mybs);
 | |
|     glopts->samples_in_buffer = 0;
 | |
| 
 | |
|     // free up the bit stream buffer structure
 | |
|     buffer_deinit(&mybs);
 | |
| 
 | |
|     return mp2_size;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| void twolame_close(twolame_options ** glopts)
 | |
| {
 | |
|     twolame_options *opts = NULL;
 | |
| 
 | |
|     // Check input pointers aren't NULL
 | |
|     if (glopts == NULL)
 | |
|         return;
 | |
|     opts = *glopts;
 | |
|     if (opts == NULL)
 | |
|         return;
 | |
| 
 | |
|     // free mem
 | |
|     psycho_4_deinit(&opts->p4mem);
 | |
|     psycho_3_deinit(&opts->p3mem);
 | |
|     psycho_2_deinit(&opts->p2mem);
 | |
|     psycho_1_deinit(&opts->p1mem);
 | |
|     psycho_0_deinit(&opts->p0mem);
 | |
| 
 | |
|     TWOLAME_FREE(opts->subband);
 | |
|     TWOLAME_FREE(opts->j_sample);
 | |
|     TWOLAME_FREE(opts->sb_sample);
 | |
| 
 | |
|     // Free the memory and zero the pointer
 | |
|     TWOLAME_FREE(opts);
 | |
| }
 | |
| 
 | |
| // vim:ts=4:sw=4:nowrap: 
 |