/* set/get functions for lame_global_flags
* Copyright (c) 2001-2005 Alexander Leidinger
*/
#include "lame.h"
#include "machine.h"
#include "encoder.h"
#include "util.h"
#include "bitstream.h" /* because of compute_flushbits */
#include "set_get.h"
#include "lame_global_flags.h"
/*
* input stream description
*/
#define FUNC(r,n) r n
/* number of samples */
/* it's unlikely for this function to return an error */
FUNC(int,lame_set_num_samples) (lame_global_flags&L, unsigned long n) {
if (!L.is_valid()) return -1;
L.set_num_samples(n); /* default = 2^32-1 */
return 0;
}
FUNC(unsigned long,lame_get_num_samples) (const lame_global_flags&L) {
if (!L.is_valid()) return 0;
return L.get_num_samples();
}
/* input samplerate */
FUNC(int,lame_set_in_samplerate) (lame_global_flags&L,int n) {
if (!L.is_valid()) return -1;
if (n < 1) return -1;
/* input sample rate in Hz, default = 44100 Hz */
L.set_in_samplerate(n);
return 0;
}
FUNC(int,lame_get_in_samplerate) (const lame_global_flags&L) {
if (!L.is_valid()) return 0;
return L.get_in_samplerate();
}
/* number of channels in input stream */
FUNC(int,lame_set_num_channels) (lame_global_flags&L,int n) {
if (!L.is_valid()) return -1;
if (n<1) return -1;
if (n>2) return -1; /* default = 2 */
L.set_num_channels(n);
return 0;
}
FUNC(int,lame_get_num_channels) (const lame_global_flags&L) {
if (!L.is_valid()) return 0;
return L.get_num_channels();
}
/* scale the input by this amount before encoding (not used for decoding) */
FUNC(int,lame_set_scale) (lame_global_flags&L,float v) {
if (!L.is_valid()) return -1;
L.set_scale(v); /* default = 1 */
return 0;
}
FUNC(float,lame_get_scale) (const lame_global_flags&L) {
if (!L.is_valid()) return 0;
return L.get_scale();
}
/* scale the channel 0 (left) input by this amount before
encoding (not used for decoding) */
int lame_global_flags::lame_set_scale_left(float v) {
if (is_valid()) {
/* default = 1 */
scale_left = v;
return 0;
}
return -1;
}
float lame_global_flags::lame_get_scale_left() const {
if (is_valid()) return scale_left;
return 0;
}
/* scale the channel 1 (right) input by this amount before
encoding (not used for decoding) */
int lame_global_flags::lame_set_scale_right(float v) {
if (is_valid()) {
/* default = 1 */
scale_right = v;
return 0;
}
return -1;
}
float lame_global_flags::lame_get_scale_right() const {
if (is_valid()) return scale_right;
return 0;
}
/* output sample rate in Hz */
FUNC(int,lame_set_out_samplerate) (lame_global_flags&L,int n) {
if (!L.is_valid()) return -1;
/*
* default = 0: LAME picks best value based on the amount
* of compression
* MPEG only allows:
* MPEG1 32, 44.1, 48khz
* MPEG2 16, 22.05, 24
* MPEG2.5 8, 11.025, 12
*
* (not used by decoding routines)
*/
if (n && SmpFrqIndex(n)<0) return -1;
L.set_out_samplerate(n);
return 0;
}
FUNC(int,lame_get_out_samplerate) (const lame_global_flags&L) {
if (!L.is_valid()) return 0;
return L.get_out_samplerate();
}
/*
* general control parameters
*/
/* collect data for an MP3 frame analzyer */
int
lame_set_analysis(lame_global_flags & gfp, int analysis)
{
if (gfp.is_valid()) {
/* default = 0 */
/* enforce disable/enable meaning, if we need more than two values
we need to switch to an enum to have an apropriate representation
of the possible meanings of the value */
if (0 > analysis || 1 < analysis)
return -1;
gfp.analysis = analysis;
return 0;
}
return -1;
}
int
lame_get_analysis(const lame_global_flags & gfp)
{
if (gfp.is_valid()) {
assert(0 <= gfp.analysis && 1 >= gfp.analysis);
return gfp.analysis;
}
return 0;
}
/* set and get some gapless encoding flags */
/********************************************************************
* Filtering control
***********************************************************************/
/*
* psycho acoustics and other arguments which you should not change
* unless you know what you are doing
*/
/*
* Allow blocktypes to differ between channels.
* default:
* 0 for jstereo => block types coupled
* 1 for stereo => block types may differ
*/
int lame_global_flags::lame_set_allow_diff_short(bool k) {
if (!is_valid()) return -1;
short_blocks = k ? short_block_allowed : short_block_coupled;
return 0;
}
bool lame_global_flags::lame_get_allow_diff_short()const{
if (is_valid()) return short_blocks == short_block_allowed;
/* true = short blocks allowed to differ */
/* false = not set, dispensed, forced or coupled */
return false;
}
/* Use temporal masking effect */
int lame_global_flags::lame_set_useTemporal(int k) {
if (!is_valid()) return -1;
/* default = 1 (enabled) */
/* enforce disable/enable meaning, if we need more than two values
we need to switch to an enum to have an apropriate representation
of the possible meanings of the value */
if (0 <= k && k <= 1) {
useTemporal = k;
return 0;
}
return -1;
}
int lame_global_flags::lame_get_useTemporal()const{
if (is_valid()) {
assert(0 <= useTemporal && 1 >= useTemporal);
return useTemporal;
}
return 0;
}
/* Use inter-channel masking effect */
int lame_global_flags::lame_set_interChRatio(float ratio) {
if (is_valid()) {
/* default = 0.0 (no inter-channel maskin) */
if (0 <= ratio && ratio <= 1.0) {
interChRatio = ratio;
return 0;
}
}
return -1;
}
float lame_global_flags::lame_get_interChRatio()const{
if (is_valid()) {
assert((0 <= interChRatio && interChRatio <= 1.0) || EQ(interChRatio, -1.0f));
return interChRatio;
}
return 0;
}
/* Use pseudo substep shaping method */
int lame_global_flags::lame_set_substep(int method) {
if (is_valid()) {
/* default = 0.0 (no substep noise shaping) */
if (0 <= method && method <= 7) {
substep_shaping = method;
return 0;
}
}
return -1;
}
int lame_global_flags::lame_get_substep()const{
if (is_valid()) {
assert(0 <= substep_shaping && substep_shaping <= 7);
return substep_shaping;
}
return 0;
}
/* scalefactors scale */
int lame_global_flags::lame_set_sfscale(bool val) {
if (!is_valid()) return -1;
noise_shaping = val ? 2 : 1;
return 0;
}
bool lame_global_flags::lame_get_sfscale()const{
if (is_valid()) return noise_shaping == 2;
return false;
}
/* subblock gain */
int lame_set_subblock_gain(lame_global_flags & gfp, int sbgain) {
if (gfp.is_valid()) {
gfp.subblock_gain = sbgain;
return 0;
}
return -1;
}
int lame_get_subblock_gain(const lame_global_flags & gfp) {
if (gfp.is_valid()) {
return gfp.subblock_gain;
}
return 0;
}
/* Disable short blocks. */
int lame_set_no_short_blocks(lame_global_flags & gfp, int no_short_blocks) {
if (gfp.is_valid()) {
/* enforce disable/enable meaning, if we need more than two values
we need to switch to an enum to have an apropriate representation
of the possible meanings of the value */
if (0 <= no_short_blocks && no_short_blocks <= 1) {
gfp.short_blocks = no_short_blocks ? short_block_dispensed : short_block_allowed;
return 0;
}
}
return -1;
}
int lame_global_flags::lame_get_no_short_blocks()const{
switch (short_blocks) {
case short_block_dispensed: return 1;
case short_block_allowed:
case short_block_coupled:
case short_block_forced: return 0;
default: return -1;
}
}
/* Force short blocks. */
int lame_set_force_short_blocks(lame_global_flags & gfp, int short_blocks) {
if (gfp.is_valid()) {
/* enforce disable/enable meaning, if we need more than two values
we need to switch to an enum to have an apropriate representation
of the possible meanings of the value */
if (0 > short_blocks || 1 < short_blocks)
return -1;
if (short_blocks == 1)
gfp.short_blocks = short_block_forced;
else if (gfp.short_blocks == short_block_forced)
gfp.short_blocks = short_block_allowed;
return 0;
}
return -1;
}
int lame_global_flags::lame_get_force_short_blocks()const{
switch (short_blocks) {
case short_block_dispensed:
case short_block_allowed:
case short_block_coupled: return 0;
case short_block_forced: return 1;
default: return -1;
}
}
void lame_global_flags::lame_set_short_threshold(float lrm, float s) {
lame_set_short_threshold_lrm(lrm);
lame_set_short_threshold_s(s);
}
/***************************************************************/
/* internal variables, cannot be set... */
/* provided because they may be of use to calling application */
/***************************************************************/
/* MPEG version.
* 0 = MPEG-2
* 1 = MPEG-1
* (2 = MPEG-2.5)
*/
int lame_global_flags::lame_get_version()const{
return internal_flags->cfg.version;
}
/* Encoder delay. */
int lame_global_flags::lame_get_encoder_delay()const{
return internal_flags->ov_enc.encoder_delay;
}
/* padding added to the end of the input */
int lame_global_flags::lame_get_encoder_padding()const{
return internal_flags->ov_enc.encoder_padding;
}
/* Size of MPEG frame. */
int lame_global_flags::lame_get_framesize()const{
// if (!gfp.is_valid()) return 0;
// lame_internal_flags const & gfc = *gfp.i;
// if (!gfc.is_valid()) return 0;
// SessionConfig_t const & cfg = gfc.cfg;
return 576 * internal_flags->cfg.mode_gr;
}
/* Number of frames encoded so far. */
int lame_global_flags::lame_get_frameNum()const{
return internal_flags->ov_enc.frame_number;
}
int lame_global_flags::lame_get_mf_samples_to_encode()const{
return internal_flags->sv_enc.mf_samples_to_encode;
}
int lame_global_flags::lame_get_size_mp3buffer()const{
int size;
internal_flags->compute_flushbits(&size);
return size;
}
int lame_global_flags::lame_get_RadioGain()const{
return internal_flags->ov_rpg.RadioGain;
}
int lame_global_flags::lame_get_AudiophileGain()const{
return 0;
}
float lame_global_flags::lame_get_PeakSample()const{
return internal_flags->ov_rpg.PeakSample;
}
int lame_global_flags::lame_get_noclipGainChange()const{
return internal_flags->ov_rpg.noclipGainChange;
}
float lame_global_flags::lame_get_noclipScale()const{
return internal_flags->ov_rpg.noclipScale;
}
/*
* LAME's estimate of the total number of frames to be encoded.
* Only valid if calling program set num_samples.
*/
int lame_global_flags::lame_get_totalframes()const{
lame_internal_flags const &gfc = *internal_flags;
SessionConfig_t const &cfg = gfc.cfg;
unsigned long const pcm_samples_per_frame = 576 * cfg.mode_gr;
unsigned long pcm_samples_to_encode = num_samples;
unsigned long end_padding = 0;
int frames = 0;
if (pcm_samples_to_encode == (0ul-1ul)) return 0; /* unknown */
/* estimate based on user set num_samples: */
if (cfg.samplerate_in != cfg.samplerate_out) {
/* resampling, estimate new samples_to_encode */
double resampled_samples_to_encode = 0.0, frames_f = 0.0;
if (cfg.samplerate_in > 0) {
resampled_samples_to_encode = pcm_samples_to_encode;
resampled_samples_to_encode *= cfg.samplerate_out;
resampled_samples_to_encode /= cfg.samplerate_in;
}
if (resampled_samples_to_encode <= 0.0) return 0; /* unlikely to happen, so what, no estimate! */
frames_f = floor(resampled_samples_to_encode / pcm_samples_per_frame);
if (frames_f >= (INT_MAX-2)) return 0; /* overflow, happens eventually, no estimate! */
frames = frames_f;
resampled_samples_to_encode -= frames * pcm_samples_per_frame;
pcm_samples_to_encode = ceil(resampled_samples_to_encode);
}else{
frames = pcm_samples_to_encode / pcm_samples_per_frame;
pcm_samples_to_encode -= frames * pcm_samples_per_frame;
}
pcm_samples_to_encode += 576ul;
end_padding = pcm_samples_per_frame - (pcm_samples_to_encode % pcm_samples_per_frame);
if (end_padding < 576ul) end_padding += pcm_samples_per_frame;
pcm_samples_to_encode += end_padding;
frames += (pcm_samples_to_encode / pcm_samples_per_frame);
/* check to see if we underestimated totalframes */
/* if (totalframes < gfp.frameNum) */
/* totalframes = gfp.frameNum; */
return frames;
}
int lame_global_flags::lame_set_preset(int k) {
if (is_valid()) {
preset = k;
return apply_preset(k,true);
}
return -1;
}
void lame_global_flags::lame_set_asm_optimizations(int optim, bool mode) {
switch (optim) {
case MMX: asm_optimizations.mmx = mode; break;
case AMD_3DNOW: asm_optimizations.amd3dnow = mode; break;
case SSE: asm_optimizations.sse = mode; break;
}
}
int lame_internal_flags::calc_maximum_input_samples_for_buffer_size(size_t buffer_size)const{
// SessionConfig_t const & cfg = gfc.cfg;
int const pcm_samples_per_frame = 576 * cfg.mode_gr;
int frames_per_buffer = 0, input_samples_per_buffer = 0;
int kbps = 320;
if (cfg.samplerate_out < 16000) kbps = 64;
else if (cfg.samplerate_out < 32000) kbps = 160;
else kbps = 320;
if (cfg.free_format) kbps = cfg.avg_bitrate;
else if (cfg.vbr == vbr_off) kbps = cfg.avg_bitrate;
{
int const pad = 1;
int const bpf = ((cfg.version + 1) * 72000 * kbps / cfg.samplerate_out + pad);
frames_per_buffer = int(buffer_size / bpf);
}
{
double ratio = (double) cfg.samplerate_in / cfg.samplerate_out;
input_samples_per_buffer = pcm_samples_per_frame * frames_per_buffer * ratio;
}
return input_samples_per_buffer;
}
int lame_global_flags::lame_get_maximum_number_of_samples(size_t buffer_size) {
return internal_flags->calc_maximum_input_samples_for_buffer_size(buffer_size);
}
Detected encoding: ASCII (7 bit) | 2
|