Ticket #8568: vuvuzela-fixes.patch

File vuvuzela-fixes.patch, 21.6 KB (added by JYA, 10 years ago)

0.23-fixes version

  • mythtv/libs/libmythtv/NuppelVideoPlayer.cpp

     
    51345134    return false;
    51355135}
    51365136
     5137bool NuppelVideoPlayer::ToggleVuvuzela()
     5138{
     5139    bool ret = false;
     5140    if (audioOutput)
     5141        ret = audioOutput->ToggleVuvuzela();
     5142    if (decoder)
     5143        decoder->SetDisablePassThrough(ret);
     5144    return ret;
     5145}
     5146
     5147bool NuppelVideoPlayer::IsVuvuzela()
     5148{
     5149    return audioOutput ? audioOutput->IsVuvuzela() : false;
     5150}
     5151
    51375152void NuppelVideoPlayer::Zoom(ZoomDirection direction)
    51385153{
    51395154    if (videoOutput)
  • mythtv/libs/libmythtv/avformatdecoder.cpp

     
    46394639    else if (ctx->codec_id == CODEC_ID_DTS)
    46404640        passthru = allow_dts_passthru && !internal_vol;
    46414641
     4642    passthru &= !GetNVP()->IsVuvuzela();
    46424643    passthru &= !transcoding && !disable_passthru;
    46434644    // Don't know any cards that support spdif clocked at < 44100
    46444645    // Some US cable transmissions have 2ch 32k AC-3 streams
  • mythtv/libs/libmythtv/tv_play.h

     
    436436                                 const QStringList &actions);
    437437
    438438    void ToggleUpmix(PlayerContext*);
     439    void ToggleVuvuzela(PlayerContext*);
    439440    void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true);
    440441    bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions);
    441442
  • mythtv/libs/libmythtv/NuppelVideoPlayer.h

     
    165165    void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle);
    166166    void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle);
    167167    bool ToggleUpmix(void);
     168    bool ToggleVuvuzela(void);
     169    bool IsVuvuzela(void);
    168170
    169171    // Gets
    170172    QSize   GetVideoBufferSize(void) const    { return video_dim; }
  • mythtv/libs/libmythtv/tv_play.cpp

     
    45164516        ToggleTimeStretch(ctx);
    45174517    else if (has_action("TOGGLEUPMIX", actions))
    45184518        ToggleUpmix(ctx);
     4519    else if (has_action("TOGGLEVUVUZELA", actions))
     4520        ToggleVuvuzela(ctx);
    45194521    else if (has_action("TOGGLESLEEP", actions))
    45204522        ToggleSleepTimer(ctx);
    45214523    else if (has_action("TOGGLERECORD", actions) && islivetv)
     
    82868288        ctx->nvp->GetOSD()->SetSettingsText(text, 5);
    82878289}
    82888290
     8291void TV::ToggleVuvuzela(PlayerContext *ctx)
     8292{
     8293    if (!ctx->nvp || !ctx->nvp->HasAudioOut())
     8294        return;
     8295    QString text;
     8296    if (ctx->nvp->ToggleVuvuzela())
     8297        text = tr("Vuvuzela Filter On");
     8298    else
     8299        text = tr("Vuvuzela Filter Off");
     8300
     8301    if (ctx->nvp->GetOSD() && !browsemode)
     8302        ctx->nvp->GetOSD()->SetSettingsText(text, 5);
     8303}
     8304
    82898305// dir in 10ms jumps
    82908306void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit)
    82918307{
     
    99499965        ToggleTimeStretch(actx);
    99509966    else if (action == "TOGGLEUPMIX")
    99519967        ToggleUpmix(actx);
     9968    else if (action == "TOGGLEVUVUZELA")
     9969        ToggleVuvuzela(actx);
    99529970    else if (action.left(13) == "ADJUSTSTRETCH")
    99539971    {
    99549972        bool floatRead;
     
    1032310341        new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC");
    1032410342    else if (category == "TOGGLEUPMIX")
    1032510343        new OSDGenericTree(treeMenu, tr("Toggle Audio Upmixer"), "TOGGLEUPMIX");
     10344    else if (category == "TOGGLEVUVUZELA")
     10345        new OSDGenericTree(treeMenu, tr("Toggle Vuvuzela Filter"), "TOGGLEVUVUZELA");
    1032610346    else if (category == "TIMESTRETCH")
    1032710347        FillMenuTimeStretch(ctx, treeMenu);
    1032810348    else if (category == "VIDEOSCAN")
  • mythtv/libs/libmythtv/tvosdmenuentry.cpp

     
    236236        "AUDIOSYNC",          1,  1,  1,  1, "Audio Sync"));
    237237    curMenuEntries.append(new TVOSDMenuEntry(
    238238        "TOGGLEUPMIX",        1,  1,  1,  1, "Toggle Upmixer"));
     239    if (gContext->GetNumSetting("AdvancedAudioSettings", false) &&
     240        gContext->GetNumSetting("VuvuzelaFilter", false))
     241    {
     242        curMenuEntries.append(new TVOSDMenuEntry(
     243            "TOGGLEVUVUZELA", 1,  1,  1,  1, "Toggle Vuvuzela Filter"));
     244    }
    239245    curMenuEntries.append(new TVOSDMenuEntry(
    240246        "TIMESTRETCH",        1,  1,  1,  1, "Time Stretch"));
    241247    curMenuEntries.append(new TVOSDMenuEntry(
  • mythtv/libs/libmyth/audiooutputbase.h

     
    1616
    1717// MythTV headers
    1818#include "audiooutput.h"
     19#include "audiooutpututil.h"
    1920#include "samplerate.h"
    2021#include "mythverbose.h"
    2122
     
    4445    virtual void SetStretchFactor(float factor);
    4546    virtual float GetStretchFactor(void) const;
    4647    virtual bool ToggleUpmix(void);
     48    virtual bool ToggleVuvuzela(void);
     49    virtual bool IsVuvuzela(void) { return vuvuzela; }
    4750
    4851    virtual void Reset(void);
    4952
     
    230233    /** main audio buffer */
    231234    unsigned char audiobuffer[kAudioRingBufferSize];
    232235    uint memory_corruption_test4;
     236
     237    //Vuvuzela filter
     238    bool vuvuzela, last_vuvuzela;
     239    AudioOutputUtil::Notch *notch_instance;
    233240};
    234241
    235242#endif
  • mythtv/libs/libmyth/audiooutpututil.h

     
     1#ifndef AUDIOOUTPUTUTIL
     2#define AUDIOOUTPUTUTIL
     3
     4using namespace std;
     5
     6#define IIR_NUM_COEFFICIENTS                            (3)     // Assumed biquads
     7
     8class AudioOutputUtil
     9{
     10 public:
     11   
     12    //Notch Filter / IRR transformation
     13    // Parameters
     14    typedef struct
     15    {
     16        uint N;
     17        uint num_biquads;
     18        float b[IIR_NUM_COEFFICIENTS];
     19        float a[IIR_NUM_COEFFICIENTS];
     20    } IIR_Parameters;
     21   
     22    // State information
     23    typedef struct
     24    {
     25        float a[IIR_NUM_COEFFICIENTS];
     26        float b[IIR_NUM_COEFFICIENTS];
     27        float x_mem[IIR_NUM_COEFFICIENTS];
     28        float y_mem[IIR_NUM_COEFFICIENTS];
     29    } IIR_State;
     30   
     31    // Instance
     32    typedef struct
     33    {
     34        IIR_Parameters parameters;
     35        IIR_State state;
     36    } IIR;
     37   
     38    // Parameters
     39    typedef struct
     40    {
     41        uint N;
     42        float frequency;                        // Notch frequency
     43        float attenuation_dB;           // Notch attenuation
     44    } Notch_Parameters;
     45
     46    // State information
     47
     48    typedef struct
     49    {
     50        float pole_position;
     51        float frequency_offset;
     52        float a1s;
     53        float a2;
     54        float depth_factor;
     55        float w0;               // Input weight
     56        float w1;               // Output weight
     57    } Notch_State;
     58
     59    // Instance
     60    typedef struct
     61    {
     62        Notch_Parameters parameters;
     63        Notch_State state;
     64        IIR iir;
     65    } Notch;
     66
     67    static void notch_update(Notch &instance, float fs);
     68    static void notch_execute(Notch &instance, float *in, float *out);
     69};
     70
     71#endif
  • mythtv/libs/libmyth/audiooutputbase.cpp

     
    1313#include "compat.h"
    1414#include "audiooutputbase.h"
    1515#include "audiooutputdigitalencoder.h"
     16#include "audiooutpututil.h"
    1617#include "SoundTouch.h"
    1718#include "freesurround.h"
    1819
     
    7374    memory_corruption_test1(0xdeadbeef),
    7475    memory_corruption_test2(0xdeadbeef),
    7576    memory_corruption_test3(0xdeadbeef),
    76     memory_corruption_test4(0xdeadbeef)
     77    memory_corruption_test4(0xdeadbeef),
     78    vuvuzela(false),            last_vuvuzela(false),
     79    notch_instance(NULL)
    7780{
    7881    // The following are not bzero() because MS Windows doesn't like it.
    7982    memset(&src_data,          0, sizeof(SRC_DATA));
     
    197200    return (configured_audio_channels == 6);
    198201}
    199202
     203bool AudioOutputBase::ToggleVuvuzela(void)
     204{
     205    vuvuzela = !vuvuzela;
     206    const AudioSettings settings(audio_bits, source_audio_channels,
     207                                 audio_codec, source_audio_samplerate,
     208                                 audio_passthru);
     209    Reconfigure(settings);
    200210
     211    return vuvuzela;
     212}
     213
    201214void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
    202215{
    203216    AudioSettings settings = orig_settings;
     
    229242        settings.samplerate == audio_samplerate && !need_resampler &&
    230243        settings.use_passthru == audio_passthru &&
    231244        lneeds_upmix == needs_upmix &&
     245        last_vuvuzela == vuvuzela &&
    232246        laudio_reenc == audio_reenc);
    233247    bool upmix_deps =
    234248        (lsource_audio_channels == source_audio_channels);
     
    247261        return;
    248262    }
    249263
     264    last_vuvuzela          = vuvuzela;
     265
    250266    KillAudio();
    251267
    252268    QMutexLocker lock1(&audio_buflock);
     
    264280    audio_codec = settings.codec;
    265281    audio_passthru = settings.use_passthru;
    266282    needs_upmix = lneeds_upmix;
     283    vuvuzela = last_vuvuzela;
    267284
    268285    if (audio_bits != 8 && audio_bits != 16)
    269286    {
     
    341358        need_resampler = true;
    342359    }
    343360
     361    if (vuvuzela)
     362    {
     363        VERBOSE(VB_AUDIO, LOC + "Vuvuzela filter enabled. Go Socceroos Go!");
     364        if (!notch_instance)
     365            notch_instance = new AudioOutputUtil::Notch;
     366    }
     367
    344368    if (audio_enc)
    345369    {
    346370        VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder");
     
    497521    needs_upmix = false;
    498522    audio_enc = false;
    499523
     524    if (notch_instance)
     525    {
     526        delete notch_instance;
     527        notch_instance = NULL;
     528    }
     529    vuvuzela = false;
     530
    500531    CloseDevice();
    501532
    502533    killAudioLock.unlock();
     
    790821            VERBOSE(VB_IMPORTANT, LOC_ERR +
    791822                    QString("Error occurred while resampling audio: %1")
    792823                    .arg(src_strerror(error)));
    793 
    794824        src_float_to_short_array(src_data.data_out, (short int*)tmp_buff,
    795825                                 src_data.output_frames_gen*audio_channels);
    796826
     
    844874    QMutexLocker lock1(&audio_buflock);
    845875
    846876    // resample input if necessary
    847     if (need_resampler && src_ctx)
     877    if ((need_resampler && src_ctx) || (vuvuzela && notch_instance))
    848878    {
    849879        // Convert to floats
    850880        short *buf_ptr = (short*)buffer;
     
    853883            src_in[sample] = (float)buf_ptr[sample] / (1.0 * 0x8000);
    854884        }
    855885 
    856         src_data.input_frames = samples;
    857         src_data.end_of_input = 0;
    858         int error = src_process(src_ctx, &src_data);
    859         if (error)
    860             VERBOSE(VB_IMPORTANT, LOC_ERR +
    861                     QString("Error occurred while resampling audio: %1")
    862                     .arg(src_strerror(error)));
    863         src_float_to_short_array(src_data.data_out, (short int*)tmp_buff,
    864                                  src_data.output_frames_gen*audio_channels);
     886        if (vuvuzela)
     887        {
     888            notch_instance->parameters.N = samples * audio_channels;
     889            // Notch attenuation
     890            notch_instance->parameters.attenuation_dB = 35.0f;
     891           
     892            // Notch frequency
     893            notch_instance->parameters.frequency = 233.0f;
     894            AudioOutputUtil::notch_update (*notch_instance, (float)source_audio_samplerate);
     895            AudioOutputUtil::notch_execute (*notch_instance, src_in, src_out);
     896            notch_instance->parameters.frequency = 466.0f;  // 1st harmonic
     897            AudioOutputUtil::notch_update (*notch_instance, (float)source_audio_samplerate);
     898            AudioOutputUtil::notch_execute (*notch_instance, src_out, src_in);
     899            notch_instance->parameters.frequency = 932.0f;  // 2nd harmonic
     900            AudioOutputUtil::notch_update (*notch_instance, (float)source_audio_samplerate);
     901            AudioOutputUtil::notch_execute (*notch_instance, src_in, src_out);
     902            notch_instance->parameters.frequency = 1864.0f;  // 3rd harmonic
     903            AudioOutputUtil::notch_update (*notch_instance, (float)source_audio_samplerate);
     904            AudioOutputUtil::notch_execute (*notch_instance, src_out, src_in);
     905        }
    865906
    866         _AddSamples(tmp_buff, true, src_data.output_frames_gen, timecode);
     907        if (need_resampler)
     908        {
     909            src_data.input_frames = samples;
     910            src_data.end_of_input = 0;
     911            int error = src_process(src_ctx, &src_data);
     912            if (error)
     913                VERBOSE(VB_IMPORTANT, LOC_ERR +
     914                        QString("Error occurred while resampling audio: %1")
     915                        .arg(src_strerror(error)));
     916            src_float_to_short_array(src_data.data_out, (short int*)tmp_buff,
     917                                     src_data.output_frames_gen*audio_channels);
     918
     919            _AddSamples(tmp_buff, true, src_data.output_frames_gen, timecode);
     920        }
     921        else
     922        {
     923            src_float_to_short_array(src_in, (short int*)tmp_buff,
     924                                     samples * audio_channels);
     925            _AddSamples(tmp_buff, true, samples, timecode);
     926        }
    867927    }
    868928    else
    869929    {
  • mythtv/libs/libmyth/libmyth.pro

     
    3030HEADERS += audiopulseutil.h
    3131HEADERS += programinfo.h programlist.h programinfoupdater.h
    3232HEADERS += recordingtypes.h remoteutil.h
    33 HEADERS += rawsettingseditor.h
     33HEADERS += rawsettingseditor.h audiooutpututil.h
    3434
    3535# remove when everything is switched to mythui
    3636HEADERS += virtualkeyboard_qt.h
     
    5454SOURCES += audiopulseutil.cpp
    5555SOURCES += programinfo.cpp programlist.cpp programinfoupdater.cpp
    5656SOURCES += recordingtypes.cpp remoteutil.cpp
    57 SOURCES += rawsettingseditor.cpp
     57SOURCES += rawsettingseditor.cpp audiooutpututil.cpp
    5858
    5959# remove when everything is switched to mythui
    6060SOURCES += virtualkeyboard_qt.cpp
  • mythtv/libs/libmyth/audiooutput.h

     
    7171    virtual void bufferOutputData(bool y) = 0;
    7272    virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0;
    7373    virtual bool ToggleUpmix(void) = 0;
     74    virtual bool ToggleVuvuzela(void) = 0;
     75    virtual bool IsVuvuzela(void) = 0;
    7476
    7577  protected:
    7678    void Error(const QString &msg);
  • mythtv/libs/libmyth/audiooutpututil.cpp

     
     1#include "dsputil.h"
     2#include "mythconfig.h"
     3#include "audiooutpututil.h"
     4
     5#define IIR_NUM_COEFFICIENTS                            (3)     // Assumed biquads
     6
     7static void iir_update (AudioOutputUtil::IIR &instance)
     8{
     9        // Clear the filter state
     10    bzero(&instance.state.x_mem[0], IIR_NUM_COEFFICIENTS * sizeof(float));
     11    bzero(&instance.state.y_mem[0], IIR_NUM_COEFFICIENTS * sizeof(float));
     12   
     13    memcpy(&instance.state.b[0], &instance.parameters.b[0],
     14           IIR_NUM_COEFFICIENTS * sizeof(float));
     15    memcpy(&instance.state.a[0], &instance.parameters.a[0],
     16           IIR_NUM_COEFFICIENTS * sizeof(float));
     17}
     18
     19/* Notch filter (c) 2010 Hydrix & Jean-Yves Avenard */
     20/* www.hydrix.com */
     21
     22// Processes a single block of samples with a single IIR biquad stage
     23//    N                   M
     24//   SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k)      for 1<=n<=length(x)
     25//   k=0                 k=0
     26// where N=length(a)-1 and M=length(b)-1.
     27// Vector s is the initial state of the system. The final state is also returned
     28// The state vector is a column vector whose length is equal to the
     29//      length of the longest coefficient vector minus one.
     30static void iir_biquad (float* x, float* y,
     31                        float* a, float* b,
     32                        float* x_mem, float* y_mem,
     33                        unsigned int N)
     34{
     35        // Direct Form I
     36        //               N+1               N+1
     37        //              y(n) = - SUM a(k) y(n-k) + SUM b(k) x(n-k)  for 0 <= n <length(x)
     38        //               k=1               k=0
     39        unsigned int n = 0;
     40        unsigned int k = 0;
     41        float y_n_minus_k = 0.0f;
     42        float x_n_minus_k = 0.0f;
     43        for (n = 0; n < N; n++)
     44        {
     45                y[n] = x[n] * b[0];
     46       
     47                for (k = 1; k < IIR_NUM_COEFFICIENTS; k++)
     48                {
     49                        signed int n_minus_k = n - k;
     50                        if (n_minus_k >= 0)
     51                        {
     52                                x_n_minus_k = x[n_minus_k];
     53                                y_n_minus_k = y[n_minus_k];
     54                        }
     55                        else
     56                        {
     57                                x_n_minus_k = x_mem[-n_minus_k-1];
     58                                y_n_minus_k = y_mem[-n_minus_k-1];
     59                        }
     60           
     61                        y[n] -= a[k] * y_n_minus_k;
     62                        y[n] += b[k] * x_n_minus_k;
     63                }
     64        }
     65   
     66        // Save input and output state, latest first
     67        unsigned int state_offset = N - 1;
     68        for (n=0; n < (IIR_NUM_COEFFICIENTS-1); n++)
     69        {
     70                x_mem[n] = x[state_offset];
     71                y_mem[n] = y[state_offset];
     72                state_offset--;
     73        }
     74}
     75
     76static void iir_execute(AudioOutputUtil::IIR &instance, float* x, float* y)
     77{
     78    iir_biquad(x, y,
     79               &instance.state.a[0], &instance.state.b[0],
     80               &instance.state.x_mem[0], &instance.state.y_mem[0],
     81               instance.parameters.N);
     82}
     83
     84// Notch filter
     85#define PI_FLOAT                    (3.14159265358979f)
     86
     87void AudioOutputUtil::notch_update (Notch &instance, float fs)
     88{
     89        instance.state.pole_position = 0.99f;
     90        instance.state.frequency_offset = 0.0f; // in normalised frequency (1.0 = fs)
     91        instance.state.a1s = -instance.state.pole_position;
     92        instance.state.a2 = -(instance.state.pole_position * instance.state.pole_position);
     93        instance.state.depth_factor = 0.999f;
     94
     95        // Calculate filter coefficients
     96        // Direct-form IIR
     97        // Ref: http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt and others
     98        float normalised_notch_frequency = (2.0f * instance.parameters.frequency / fs);
     99        normalised_notch_frequency += instance.state.frequency_offset;
     100        float frequency_factor = -2.0f * cosf(PI_FLOAT * normalised_notch_frequency);
     101        float a1 = frequency_factor * instance.state.a1s;
     102        float a2 = instance.state.a2;
     103        float b1 = frequency_factor * instance.state.depth_factor;
     104        float b2 = instance.state.depth_factor * instance.state.depth_factor;
     105        instance.iir.parameters.N = instance.parameters.N;
     106        instance.iir.parameters.a[0] = 1.0f;
     107        instance.iir.parameters.a[1] = -a1;
     108        instance.iir.parameters.a[2] = -a2;
     109        instance.iir.parameters.b[0] = 1.0f;
     110        instance.iir.parameters.b[1] = b1;
     111        instance.iir.parameters.b[2] = b2;
     112
     113        // Initialise the IIR stage
     114        iir_update(instance.iir);
     115
     116        // The notch filter strongly attenuates at the notch frequency.
     117        // The output is the weighted sum of the input and the
     118        //      notch-filtered input.  The weights are calculated from the
     119        //      attenuation parameters
     120        // instance.state.w0 = pow(10.0, (-instance.parameters.attenuation_dB / 20.0));
     121        // instance.state.w1 = 1.0 - instance.state.w0;
     122        float w0 = powf(10.0f, (-instance.parameters.attenuation_dB / 20.0f));
     123        float w1 = 1.0f - w0;
     124        instance.state.w0 = w0;
     125        instance.state.w1 = w1;
     126
     127        return;
     128}
     129
     130// Processes a single block of samples
     131void AudioOutputUtil::notch_execute (Notch &instance, float *in, float *out)
     132{
     133    // Apply the rejection filter
     134    iir_execute(instance.iir, in, out);
     135
     136    // The output is the weighted sum of the input and the
     137    //  notch-filtered input
     138    for (uint i=0; i < instance.parameters.N; i++)
     139    {
     140        out[i] *= instance.state.w1;
     141        out[i] += instance.state.w0 * in[i];
     142    }
     143}
  • mythtv/programs/mythfrontend/globalsettings.cpp

     
    181181    return gc;
    182182}
    183183
     184static HostCheckBox *VuvuzelaFilter()
     185{
     186    HostCheckBox *gc = new HostCheckBox("VuvuzelaFilter");
     187    gc->setLabel(QObject::tr("Enable vuvuzela filter"));
     188    gc->setValue(false);
     189    gc->setHelpText(QObject::tr("With this option enabled, a dedicated vuvuzela "
     190                                "filter option will be accessible in the playback "
     191                                "menu"));
     192    return gc;
     193}
     194
    184195static HostCheckBox *MythControlsVolume()
    185196{
    186197    HostCheckBox *gc = new HostCheckBox("MythControlsVolume");
     
    34853496    settings2->addChild(srcqualityoverride);
    34863497    settings2->addChild(sub3);
    34873498   
     3499    group2->addChild(VuvuzelaFilter());
    34883500    group2->addChild(settings2);
    34893501    group2->addChild(AggressiveBuffer());
    34903502
  • mythtv/programs/mythtranscode/transcode.cpp

     
    217217        // Do nothing
    218218        return false;
    219219    }
    220 
     220    virtual bool ToggleVuvuzela(void)
     221    {
     222        // Do nothing
     223        return false;
     224    }
     225    virtual bool IsVuvuzela(void)
     226    {
     227        // Do nothing
     228        return false;
     229    }
    221230    virtual void SetSWVolume(int new_volume, bool save)
    222231    {
    223232        // Do nothing