Ticket #4804: preamp-r16313.patch

File preamp-r16313.patch, 6.6 KB (added by chhamilton@…, 12 years ago)

Patch adding software preamp to libmyth/AudioOutput.

  • audiooutputbase.h

     
    5050                             int   audio_samplerate,
    5151                             bool  audio_passthru,
    5252                             void *audio_codec = NULL);
     53
     54    // For software pre-amplification.
     55    virtual bool IsPreAmpEnabled() const;
     56        virtual void SetPreAmp(bool enabled);
     57    virtual void EnablePreAmp();
     58    virtual void DisablePreAmp();
     59    virtual void SetPreAmpGain(float gain);
     60    virtual void SetPreAmpFactor(float factor);
     61    virtual float GetPreAmpGain() const;
     62    virtual float GetPreAmpFactor() const;
     63    virtual void ResetClippingMonitor();
     64    virtual bool HasClippingOccurred() const;
     65    virtual float GetMaxOutput() const;
     66    virtual float GetMaxClipFreePreAmpGain() const;
     67    virtual float GetMaxClipFreePreAmpFactor() const;
    5368   
    5469    // do AddSamples calls block?
    5570    virtual void SetBlocking(bool blocking);
     
    104119
    105120    int GetAudioData(unsigned char *buffer, int buf_size, bool fill_buffer);
    106121
     122    void ApplyPreAmp(void *buffer, int samples, int sample_bytes);
    107123    void _AddSamples(void *buffer, bool interleaved, int samples, long long timecode);
    108124 
    109125    void KillAudio();
     
    161177    float src_out[AUDIO_SRC_OUT_SIZE];
    162178    short tmp_buff[AUDIO_TMP_BUF_SIZE];
    163179
     180    // pre-amplification
     181    bool pre_amp_enabled;
     182    float pre_amp_factor;
     183    float pre_amp_max_output;
     184
    164185    // timestretch
    165186    soundtouch::SoundTouch    *pSoundStretch;
    166187    AudioOutputDigitalEncoder *encoder;
  • audiooutputbase.cpp

     
    22#include <cstdio>
    33#include <cstdlib>
    44#include <cmath>
     5#include <climits>
     6#include <cfloat>
    57
    68// POSIX headers
    79#include <pthread.h>
     
    5052    need_resampler(false),
    5153
    5254    src_ctx(NULL),
     55   
     56    pre_amp_enabled(false),     pre_amp_factor(1.0),
     57    pre_amp_max_output(0.0),
    5358
    5459    pSoundStretch(NULL),       
    5560    encoder(NULL),
     
    846851    return len;
    847852}
    848853
     854#define __APPLY_PRE_AMP(TYPE,MIN,MAX) \
     855        { \
     856        TYPE *buf = (TYPE *)buffer; \
     857    for ( int i = 0; i < samples; ++i ) \
     858    { \
     859        float f = (float)buf[i] / (float)MAX; \
     860        f *= pre_amp_factor; \
     861        float a = abs(f); \
     862        if ( a > pre_amp_max_output ) pre_amp_max_output = a; \
     863        if ( f >= 1.0 ) buf[i] = MAX; \
     864        else if ( f <= -1.0 ) buf[i] = MIN; \
     865        else buf[i] = (TYPE)round(f*MAX); \
     866    } \
     867        }
     868void AudioOutputBase::ApplyPreAmp(void *buffer, int samples, int sample_bytes)
     869{
     870    if ( !pre_amp_enabled ) return;
     871    // NOTE: This only handles 1, 2 or 4 byte samples.
     872    if ( sample_bytes == 4 )
     873                __APPLY_PRE_AMP(int,INT_MIN,INT_MAX)
     874    else if ( sample_bytes == 2 )
     875                __APPLY_PRE_AMP(short,SHRT_MIN,SHRT_MAX)
     876    else if ( sample_bytes == 1 )
     877                __APPLY_PRE_AMP(char,CHAR_MIN,CHAR_MAX)
     878    return;
     879}
     880#undef __APPLY_PRE_AMP
     881
    849882void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples,
    850883                                  long long timecode)
    851884{
     
    854887    int len; // = samples * audio_bytes_per_sample;
    855888    int audio_bytes = audio_bits / 8;
    856889    int org_waud = waud;
    857    
     890
     891    if ( interleaved )
     892        // Apply to the single buffer if we're interleaved.
     893        ApplyPreAmp(buffer,samples*source_audio_channels,audio_bytes);
     894    else
     895    {
     896        // Otherwise, apply to each channel individually.
     897        void **bufs = (void**)buffer;
     898        for ( int i = 0; i < source_audio_channels; ++i )
     899            ApplyPreAmp(bufs[i],samples,audio_bytes);
     900    }
     901
    858902    int afree = audiofree(false);
    859903
    860904    int abps = (encoder) ?
     
    13451389    return 0;
    13461390}
    13471391
     1392bool AudioOutputBase::IsPreAmpEnabled() const
     1393{
     1394    return pre_amp_enabled;
     1395}
     1396
     1397void AudioOutputBase::SetPreAmp(bool enabled)
     1398{
     1399        pre_amp_enabled = enabled;
     1400        return;
     1401}
     1402
     1403void AudioOutputBase::EnablePreAmp()
     1404{
     1405    pre_amp_enabled = true;
     1406    return;
     1407}
     1408
     1409void AudioOutputBase::DisablePreAmp()
     1410{
     1411    pre_amp_enabled = false;
     1412    return;
     1413}
     1414
     1415void AudioOutputBase::SetPreAmpGain(float gain)
     1416{
     1417    pre_amp_factor = pow(10.0,gain/20.0);
     1418    return;
     1419}
     1420
     1421void AudioOutputBase::SetPreAmpFactor(float factor)
     1422{
     1423    if ( factor >= 0 ) pre_amp_factor = factor;
     1424    return;
     1425}
     1426
     1427float AudioOutputBase::GetPreAmpGain() const
     1428{
     1429    if ( pre_amp_factor <= 0 ) return -1.0*FLT_MAX;
     1430    return 20.0*log(pre_amp_factor)/log(10.0);
     1431}
     1432
     1433float AudioOutputBase::GetPreAmpFactor() const
     1434{
     1435    return pre_amp_factor;
     1436}
     1437
     1438void AudioOutputBase::ResetClippingMonitor()
     1439{
     1440    pre_amp_max_output = 0.0;
     1441    return;
     1442}
     1443
     1444bool AudioOutputBase::HasClippingOccurred() const
     1445{
     1446    return pre_amp_max_output > 1.0;
     1447}
     1448
     1449float AudioOutputBase::GetMaxOutput() const
     1450{
     1451    return pre_amp_max_output;
     1452}
     1453
     1454float AudioOutputBase::GetMaxClipFreePreAmpGain() const
     1455{
     1456    float max_factor = GetMaxClipFreePreAmpFactor();
     1457    if ( max_factor <= 0 ) return -1.0*FLT_MAX;
     1458    return 20.0*log(max_factor)/log(10.0);
     1459}
     1460
     1461float AudioOutputBase::GetMaxClipFreePreAmpFactor() const
     1462{
     1463    if ( pre_amp_max_output == 0 ) return FLT_MAX;
     1464    return pre_amp_factor / pre_amp_max_output;
     1465}
     1466
    13481467/* vim: set expandtab tabstop=4 shiftwidth=4: */
    1349 
  • audiooutput.h

     
    3636                             int audio_samplerate,
    3737                             bool audio_passthru,
    3838                             void* audio_codec = NULL) = 0;
     39
     40    // For software pre-amplification.
     41    virtual bool IsPreAmpEnabled() const { return false; }
     42        virtual void SetPreAmp(bool enabled) { return; }
     43    virtual void EnablePreAmp() { return; }
     44        virtual void DisablePreAmp() { return; }
     45    virtual void SetPreAmpGain(float gain) { return; }
     46    virtual void SetPreAmpFactor(float factor) { return; }
     47    virtual float GetPreAmpGain() const { return 0.0; }
     48    virtual float GetPreAmpFactor() const { return 1.0; }
     49    virtual void ResetClippingMonitor() { return; }
     50    virtual bool HasClippingOccurred() const { return false; }
     51    virtual float GetMaxOutput() const { return 1.0; }
     52    virtual float GetMaxClipFreePreAmpGain() const { return 0.0; }
     53    virtual float GetMaxClipFreePreAmpFactor() const { return 1.0; }
    3954   
    4055    virtual void SetStretchFactor(float factor);
    4156    virtual float GetStretchFactor(void) { return 1.0f; }