Source file: /~heha/hsn/puh.zip/set_get.cpp

/* 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