Files
banban/ql-application/threadx/interface/custom_app/lib/libshine/layer3.c
T

209 lines
5.9 KiB
C

/* layer3.c */
#include "layer3.h"
#include "bitstream.h"
#include "l3bitstream.h"
#include "l3loop.h"
#include "l3mdct.h"
#include "l3subband.h"
#include "tables.h"
#include "types.h"
static int granules_per_frame[4] = {
1, /* MPEG 2.5 */
-1, /* Reserved */
1, /* MPEG II */
2 /* MPEG I */
};
/* Set default values for important vars */
void shine_set_config_mpeg_defaults(shine_mpeg_t *mpeg) {
mpeg->bitr = 128;
mpeg->emph = NONE;
mpeg->copyright = 0;
mpeg->original = 1;
}
int shine_mpeg_version(int samplerate_index) {
/* Pick mpeg version according to samplerate index. */
if (samplerate_index < 3)
/* First 3 samplerates are for MPEG-I */
return MPEG_I;
else if (samplerate_index < 6)
/* Then it's MPEG-II */
return MPEG_II;
else
/* Finally, MPEG-2.5 */
return MPEG_25;
}
int shine_find_samplerate_index(int freq) {
int i;
for (i = 0; i < 9; i++)
if (freq == samplerates[i])
return i;
return -1; /* error - not a valid samplerate for encoder */
}
int shine_find_bitrate_index(int bitr, int mpeg_version) {
int i;
for (i = 0; i < 16; i++)
if (bitr == bitrates[i][mpeg_version])
return i;
return -1; /* error - not a valid samplerate for encoder */
}
int shine_check_config(int freq, int bitr) {
int samplerate_index, bitrate_index, mpeg_version;
samplerate_index = shine_find_samplerate_index(freq);
if (samplerate_index < 0)
return -1;
mpeg_version = shine_mpeg_version(samplerate_index);
bitrate_index = shine_find_bitrate_index(bitr, mpeg_version);
if (bitrate_index < 0)
return -1;
return mpeg_version;
}
int shine_samples_per_pass(shine_t s) {
return s->mpeg.granules_per_frame * GRANULE_SIZE;
}
/* Compute default encoding values. */
shine_global_config *shine_initialise(shine_config_t *pub_config) {
double avg_slots_per_frame;
shine_global_config *config;
if (shine_check_config(pub_config->wave.samplerate, pub_config->mpeg.bitr) <
0)
return NULL;
config = calloc(1, sizeof(shine_global_config));
if (config == NULL)
return config;
shine_subband_initialise(config);
shine_mdct_initialise(config);
shine_loop_initialise(config);
/* Copy public config. */
config->wave.channels = pub_config->wave.channels;
config->wave.samplerate = pub_config->wave.samplerate;
config->mpeg.mode = pub_config->mpeg.mode;
config->mpeg.bitr = pub_config->mpeg.bitr;
config->mpeg.emph = pub_config->mpeg.emph;
config->mpeg.copyright = pub_config->mpeg.copyright;
config->mpeg.original = pub_config->mpeg.original;
/* Set default values. */
config->ResvMax = 0;
config->ResvSize = 0;
config->mpeg.layer = LAYER_III;
config->mpeg.crc = 0;
config->mpeg.ext = 0;
config->mpeg.mode_ext = 0;
config->mpeg.bits_per_slot = 8;
config->mpeg.samplerate_index =
shine_find_samplerate_index(config->wave.samplerate);
config->mpeg.version = shine_mpeg_version(config->mpeg.samplerate_index);
config->mpeg.bitrate_index =
shine_find_bitrate_index(config->mpeg.bitr, config->mpeg.version);
config->mpeg.granules_per_frame = granules_per_frame[config->mpeg.version];
/* Figure average number of 'slots' per frame. */
avg_slots_per_frame =
((double)config->mpeg.granules_per_frame * GRANULE_SIZE /
((double)config->wave.samplerate)) *
(1000 * (double)config->mpeg.bitr / (double)config->mpeg.bits_per_slot);
config->mpeg.whole_slots_per_frame = (int)avg_slots_per_frame;
config->mpeg.frac_slots_per_frame =
avg_slots_per_frame - (double)config->mpeg.whole_slots_per_frame;
config->mpeg.slot_lag = -config->mpeg.frac_slots_per_frame;
if (config->mpeg.frac_slots_per_frame == 0)
config->mpeg.padding = 0;
shine_open_bit_stream(&config->bs, BUFFER_SIZE);
memset((char *)&config->side_info, 0, sizeof(shine_side_info_t));
/* determine the mean bitrate for main data */
if (config->mpeg.granules_per_frame == 2) /* MPEG 1 */
config->sideinfo_len = 8 * ((config->wave.channels == 1) ? 4 + 17 : 4 + 32);
else /* MPEG 2 */
config->sideinfo_len = 8 * ((config->wave.channels == 1) ? 4 + 9 : 4 + 17);
return config;
}
static unsigned char *shine_encode_buffer_internal(shine_global_config *config,
int *written, int stride) {
if (config->mpeg.frac_slots_per_frame) {
config->mpeg.padding =
(config->mpeg.slot_lag <= (config->mpeg.frac_slots_per_frame - 1.0));
config->mpeg.slot_lag +=
(config->mpeg.padding - config->mpeg.frac_slots_per_frame);
}
config->mpeg.bits_per_frame =
8 * (config->mpeg.whole_slots_per_frame + config->mpeg.padding);
config->mean_bits = (config->mpeg.bits_per_frame - config->sideinfo_len) /
config->mpeg.granules_per_frame;
/* apply mdct to the polyphase output */
shine_mdct_sub(config, stride);
/* bit and noise allocation */
shine_iteration_loop(config);
/* write the frame to the bitstream */
shine_format_bitstream(config);
/* Return data. */
*written = config->bs.data_position;
config->bs.data_position = 0;
return config->bs.data;
}
unsigned char *shine_encode_buffer(shine_global_config *config, int16_t **data,
int *written) {
config->buffer[0] = data[0];
if (config->wave.channels == 2)
config->buffer[1] = data[1];
return shine_encode_buffer_internal(config, written, 1);
}
unsigned char *shine_encode_buffer_interleaved(shine_global_config *config,
int16_t *data, int *written) {
config->buffer[0] = data;
if (config->wave.channels == 2)
config->buffer[1] = data + 1;
return shine_encode_buffer_internal(config, written, config->wave.channels);
}
unsigned char *shine_flush(shine_global_config *config, int *written) {
*written = config->bs.data_position;
config->bs.data_position = 0;
return config->bs.data;
}
void shine_close(shine_global_config *config) {
shine_close_bit_stream(&config->bs);
free(config);
}