Ticket #8568: vuvuzela-trunk25124.2.patch

File vuvuzela-trunk25124.2.patch, 20.0 KB (added by jyavenard, 2 years ago)

Updated to remove weight sum with original signal

  • mythtv/libs/libmythtv/tv_play.h

     
    433433                                 const QStringList &actions); 
    434434 
    435435    void ToggleUpmix(PlayerContext*); 
     436    void ToggleVuvuzela(PlayerContext*); 
    436437    void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true); 
    437438    bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions); 
    438439 
  • mythtv/libs/libmythtv/audioplayer.cpp

     
    269269    return toggle; 
    270270} 
    271271 
     272bool AudioPlayer::ToggleVuvuzela(void) 
     273{ 
     274    bool toggle = false; 
     275    m_lock.lock(); 
     276    if (m_audioOutput) 
     277        toggle = m_audioOutput->ToggleVuvuzela(); 
     278    if (m_parent->GetDecoder()) 
     279        m_parent->GetDecoder()->SetDisablePassThrough(toggle);         
     280    m_lock.unlock(); 
     281    return toggle; 
     282} 
     283 
     284bool AudioPlayer::IsVuvuzela(void) 
     285{ 
     286    return m_audioOutput ? m_audioOutput->IsVuvuzela() : false; 
     287} 
     288 
    272289void AudioPlayer::SetStretchFactor(float factor) 
    273290{ 
    274291    m_stretchfactor = factor; 
  • mythtv/libs/libmythtv/tv_play.cpp

     
    42194219        ToggleTimeStretch(ctx); 
    42204220    else if (has_action("TOGGLEUPMIX", actions)) 
    42214221        ToggleUpmix(ctx); 
     4222    else if (has_action("TOGGLEVUVUZELA", actions)) 
     4223        ToggleVuvuzela(ctx); 
    42224224    else if (has_action("TOGGLESLEEP", actions)) 
    42234225        ToggleSleepTimer(ctx); 
    42244226    else if (has_action("TOGGLERECORD", actions) && islivetv) 
     
    78747876        SetOSDMessage(ctx, text); 
    78757877} 
    78767878 
     7879void TV::ToggleVuvuzela(PlayerContext *ctx) 
     7880{ 
     7881    if (!ctx->nvp || !ctx->nvp->HasAudioOut()) 
     7882        return; 
     7883    QString text; 
     7884    if (ctx->nvp->GetAudio()->ToggleVuvuzela()) 
     7885        text = tr("Vuvuzela Filter On"); 
     7886    else 
     7887        text = tr("Vuvuzela Filter Off"); 
     7888 
     7889    if (!browsemode) 
     7890        SetOSDMessage(ctx, text); 
     7891} 
     7892 
    78777893// dir in 10ms jumps 
    78787894void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit) 
    78797895{ 
     
    96399655        ToggleTimeStretch(actx); 
    96409656    else if (action == "TOGGLEUPMIX") 
    96419657        ToggleUpmix(actx); 
     9658    else if (action == "TOGGLEVUVUZELA") 
     9659        ToggleVuvuzela(actx); 
    96429660    else if (action.left(13) == "ADJUSTSTRETCH") 
    96439661    { 
    96449662        bool floatRead; 
     
    99169934 
    99179935    if (category == "DVD" && top && (ctx->GetState() == kState_WatchingDVD)) 
    99189936    { 
    9919         osd->DialogAddButton(tr("DVD Root Menu"),        "JUMPTODVDROOTMENU"); 
    9920         osd->DialogAddButton(tr("DVD Title Menu"),       "JUMPTODVDTITLEMENU"); 
    9921         osd->DialogAddButton(tr("DVD Chapter Menu"),     "JUMPTODVDCHAPTERMENU"); 
     9937        osd->DialogAddButton(tr("DVD Root Menu"),          "JUMPTODVDROOTMENU"); 
     9938        osd->DialogAddButton(tr("DVD Title Menu"),         "JUMPTODVDTITLEMENU"); 
     9939        osd->DialogAddButton(tr("DVD Chapter Menu"),       "JUMPTODVDCHAPTERMENU"); 
    99229940    } 
    99239941    else if (category == "GUIDE" && top) 
    9924         osd->DialogAddButton(tr("Program Guide"),        "GUIDE"); 
     9942        osd->DialogAddButton(tr("Program Guide"),          "GUIDE"); 
    99259943    else if (category == "EDITCHANNEL" && top) 
    9926         osd->DialogAddButton(tr("Edit Channel"),         "EDIT"); 
     9944        osd->DialogAddButton(tr("Edit Channel"),           "EDIT"); 
    99279945    else if (category == "EDITRECORDING" && top) 
    9928         osd->DialogAddButton(tr("Edit Recording"),       "EDIT"); 
     9946        osd->DialogAddButton(tr("Edit Recording"),         "EDIT"); 
    99299947    else if (category == "TOGGLEBROWSE" && top && !db_browse_always) 
    9930         osd->DialogAddButton(tr("Enable Browse Mode"),   "TOGGLEBROWSE"); 
     9948        osd->DialogAddButton(tr("Enable Browse Mode"),     "TOGGLEBROWSE"); 
    99319949    else if ( category == "PREVCHAN" && top) 
    9932         osd->DialogAddButton(tr("Previous Channel"),     "PREVCHAN"); 
     9950        osd->DialogAddButton(tr("Previous Channel"),       "PREVCHAN"); 
    99339951    else if (category == "AUDIOSYNC" && top) 
    9934         osd->DialogAddButton(tr("Adjust Audio Sync"),    "TOGGLEAUDIOSYNC"); 
     9952        osd->DialogAddButton(tr("Adjust Audio Sync"),      "TOGGLEAUDIOSYNC"); 
    99359953    else if (category == "TOGGLEUPMIX" && top) 
    9936         osd->DialogAddButton(tr("Toggle Audio Upmixer"), "TOGGLEUPMIX"); 
     9954        osd->DialogAddButton(tr("Toggle Audio Upmixer"),   "TOGGLEUPMIX"); 
     9955    else if (category == "TOGGLEVUVUZELA" && top) 
     9956        osd->DialogAddButton(tr("Toggle Vuvuzela Filter"), "TOGGLEVUVUZELA"); 
    99379957    else if (category == "MANUALZOOM"  && mainCtx && top) 
    9938         osd->DialogAddButton(tr("Manual Zoom Mode"),     "TOGGLEMANUALZOOM"); 
     9958        osd->DialogAddButton(tr("Manual Zoom Mode"),       "TOGGLEMANUALZOOM"); 
    99399959    else if (category == "TRANSCODE") 
    99409960        title = FillOSDMenuTranscode(ctx, osd, select, level); 
    99419961    else if (category == "COMMSKIP") 
  • mythtv/libs/libmythtv/tvosdmenuentry.cpp

     
    11#include "tvosdmenuentry.h" 
    22#include "mythdb.h" 
    33#include "mythverbose.h" 
     4#include "mythcorecontext.h" 
    45 
    56#define LOC QString("OSDMenuEntry:") 
    67#define LOC_ERR QString("OSDMenuEntry Error:") 
     
    243244        "AUDIOSYNC",          1,  1,  1,  1, "Audio Sync")); 
    244245    curMenuEntries.append(new TVOSDMenuEntry( 
    245246        "TOGGLEUPMIX",        1,  1,  1,  1, "Toggle Upmixer")); 
     247    if (gCoreContext->GetNumSetting("AdvancedAudioSettings", false) && 
     248        gCoreContext->GetNumSetting("VuvuzelaFilter", false)) 
     249    { 
     250        curMenuEntries.append(new TVOSDMenuEntry( 
     251            "TOGGLEVUVUZELA",        1,  1,  1,  1, "Toggle Vuvuzela Filter")); 
     252    } 
    246253    curMenuEntries.append(new TVOSDMenuEntry( 
    247254        "TIMESTRETCH",        1,  1,  1,  1, "Time Stretch")); 
    248255    curMenuEntries.append(new TVOSDMenuEntry( 
  • mythtv/libs/libmythtv/audioplayer.h

     
    3333    float GetStretchFactor(void) { return m_stretchfactor;   } 
    3434    void  SetStretchFactor(float factor); 
    3535    bool  ToggleUpmix(void); 
     36    bool  ToggleVuvuzela(void); 
     37    bool  IsVuvuzela(void); 
    3638    long long GetAudioTime(void); 
    3739 
    3840    bool      IsMuted(void) { return GetMuteState() == kMuteAll; } 
  • mythtv/libs/libmyth/audiooutputbase.h

     
    1717// MythTV headers 
    1818#include "audiooutput.h" 
    1919#include "audiooutputsettings.h" 
     20#include "audiooutpututil.h" 
    2021#include "samplerate.h" 
    2122#include "mythverbose.h" 
    2223 
     
    5051 
    5152    virtual bool CanPassthrough(void) const; 
    5253    virtual bool ToggleUpmix(void); 
     54    virtual bool ToggleVuvuzela(void); 
     55    virtual bool IsVuvuzela(void) { return vuvuzela; } 
    5356 
    5457    virtual void Reset(void); 
    5558 
     
    211214    /** main audio buffer */ 
    212215    uchar audiobuffer[kAudioRingBufferSize]; 
    213216    uint memory_corruption_test3; 
     217 
     218    //Vuvuzela filter 
     219    bool vuvuzela, last_vuvuzela; 
     220    AudioOutputUtil::Notch *notch_instance; 
    214221}; 
    215222 
    216223#endif 
  • mythtv/libs/libmyth/audiooutpututil.h

     
    55#include "mythverbose.h" 
    66#include "audiooutputsettings.h" 
    77 
     8#define IIR_NUM_COEFFICIENTS    (3)     // Assumed biquads 
     9 
    810class AudioOutputUtil 
    911{ 
    1012 public: 
     13  
     14    //Notch Filter / IRR transformation 
     15    // Parameters 
     16    typedef struct 
     17    { 
     18        uint N; 
     19        uint num_biquads; 
     20        float b[IIR_NUM_COEFFICIENTS]; 
     21        float a[IIR_NUM_COEFFICIENTS]; 
     22    } IIR_Parameters; 
     23     
     24    // State information 
     25    typedef struct 
     26    { 
     27        float a[IIR_NUM_COEFFICIENTS]; 
     28        float b[IIR_NUM_COEFFICIENTS]; 
     29        float x_mem[IIR_NUM_COEFFICIENTS]; 
     30        float y_mem[IIR_NUM_COEFFICIENTS]; 
     31    } IIR_State; 
     32 
     33    // Instance 
     34    typedef struct 
     35    { 
     36        IIR_Parameters parameters; 
     37        IIR_State state; 
     38    } IIR; 
     39 
     40    // Parameters 
     41    typedef struct 
     42    { 
     43        uint N; 
     44        float frequency;        // Notch frequency 
     45    } Notch_Parameters; 
     46 
     47    // State information 
     48 
     49    typedef struct 
     50    { 
     51        float pole_position; 
     52        float frequency_offset; 
     53        float a1s; 
     54        float a2; 
     55        float depth_factor; 
     56    } Notch_State; 
     57 
     58    // Instance 
     59    typedef struct 
     60    { 
     61        Notch_Parameters parameters; 
     62        Notch_State state; 
     63        IIR iir; 
     64    } Notch; 
     65 
    1166    static int  toFloat(AudioFormat format, void *out, void *in, int bytes); 
    1267    static int  fromFloat(AudioFormat format, void *out, void *in, int bytes); 
    1368    static void MonoToStereo(void *dst, void *src, int samples); 
     
    1570                             bool music, bool upmix); 
    1671    static void MuteChannel(int obits, int channels, int ch, 
    1772                            void *buffer, int bytes); 
     73    static void notch_update(Notch &instance, float fs); 
     74    static void notch_execute(Notch &instance, float *in, float *out); 
    1875}; 
    1976 
    2077#endif 
  • mythtv/libs/libmyth/audiooutputbase.cpp

     
    9494    memory_corruption_test0(0xdeadbeef), 
    9595    memory_corruption_test1(0xdeadbeef), 
    9696    memory_corruption_test2(0xdeadbeef), 
    97     memory_corruption_test3(0xdeadbeef) 
     97    memory_corruption_test3(0xdeadbeef), 
     98    vuvuzela(false),            last_vuvuzela(false), 
     99    notch_instance(NULL) 
    98100{ 
    99101    src_in = (float *)AOALIGN(src_in_buf); 
    100102    // The following are not bzero() because MS Windows doesn't like it. 
     
    240242} 
    241243 
    242244/** 
     245 * Toggle Vuvuzela filter 
     246 */ 
     247bool AudioOutputBase::ToggleVuvuzela(void) 
     248{ 
     249    // Reset audiobuffer now to prevent click 
     250    audio_buflock.lock(); 
     251    avsync_lock.lock(); 
     252    waud = raud = 0; 
     253 
     254    vuvuzela = !vuvuzela; 
     255    const AudioSettings settings(format, source_channels, codec, 
     256                                 source_samplerate, passthru); 
     257    audio_buflock.unlock(); 
     258    avsync_lock.unlock(); 
     259    Reconfigure(settings); 
     260 
     261    return vuvuzela; 
     262} 
     263 
     264/** 
    243265 * (Re)Configure AudioOutputBase 
    244266 * 
    245267 * Must be called from concrete subclasses 
     
    303325                        settings.use_passthru == passthru && 
    304326                        lneeds_upmix == needs_upmix && lreenc == reenc && 
    305327                        lsource_channels == source_channels && 
     328                        last_vuvuzela == vuvuzela && 
    306329                        lneeds_downmix == needs_downmix; 
    307330 
    308331    if (general_deps) 
     
    311334        return; 
    312335    } 
    313336 
     337    last_vuvuzela          = vuvuzela; 
     338 
    314339    KillAudio(); 
    315340 
    316341    QMutexLocker lock(&audio_buflock); 
     
    328353    needs_downmix          = lneeds_downmix; 
    329354    format                 = output_format   = settings.format; 
    330355    source_samplerate      = samplerate      = settings.samplerate; 
     356    vuvuzela               = last_vuvuzela; 
    331357 
    332358    killaudio = pauseaudio = false; 
    333359    was_paused = true; 
     
    415441    // Turn on float conversion? 
    416442    if (need_resampler || needs_upmix || needs_downmix || 
    417443        stretchfactor != 1.0f || (internal_vol && SWVolume()) || 
    418         (enc && output_format != FORMAT_S16) || 
     444        (enc && output_format != FORMAT_S16) || vuvuzela || 
    419445        !output_settings->IsSupportedFormat(output_format)) 
    420446    { 
    421447        VBAUDIO("Audio processing enabled"); 
     
    426452            output_format = output_settings->BestSupportedFormat(); 
    427453    } 
    428454 
     455    if (vuvuzela) 
     456    { 
     457        VBAUDIO("Vuvuzela filter enabled. Go Socceroos Go!"); 
     458        if (!notch_instance) 
     459            notch_instance = new AudioOutputUtil::Notch; 
     460    } 
     461 
    429462    if (passthru) 
    430463        channels = 2; // IEC958 bitstream - 2 ch 
    431464 
     
    560593        src_ctx = NULL; 
    561594    } 
    562595 
    563     needs_upmix = need_resampler = enc = false; 
     596    if (notch_instance) 
     597    { 
     598        delete notch_instance; 
     599        notch_instance = NULL; 
     600    } 
    564601 
     602    needs_upmix = need_resampler = enc = vuvuzela = false; 
     603 
    565604    CloseDevice(); 
    566605 
    567606    killAudioLock.unlock(); 
     
    943982            return false; // would overflow 
    944983    } 
    945984 
     985    if (vuvuzela && notch_instance) 
     986    { 
     987        notch_instance->parameters.N = frames * channels; 
     988 
     989            // Notch frequency 
     990        notch_instance->parameters.frequency = 235.0f; 
     991        AudioOutputUtil::notch_update (*notch_instance, (float)source_samplerate); 
     992        AudioOutputUtil::notch_execute (*notch_instance, src_in, src_out); 
     993        notch_instance->parameters.frequency = 465.0f;  // 1st harmonic 
     994        AudioOutputUtil::notch_update (*notch_instance, (float)source_samplerate); 
     995        AudioOutputUtil::notch_execute (*notch_instance, src_out, src_in); 
     996    } 
     997 
    946998    // Perform downmix if necessary 
    947999    if (needs_downmix) 
    9481000        if(AudioOutputDownmix::DownmixFrames(source_channels, channels, 
  • mythtv/libs/libmyth/audiooutput.h

     
    6969    virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 
    7070 
    7171    virtual bool ToggleUpmix(void) = 0; 
     72    virtual bool ToggleVuvuzela(void) = 0; 
     73    virtual bool IsVuvuzela(void) = 0; 
    7274 
    7375  protected: 
    7476    void Error(const QString &msg); 
  • mythtv/libs/libmyth/audiooutpututil.cpp

     
    610610    else 
    611611        _MuteChannel((int *)buffer, channels, ch, frames); 
    612612} 
     613 
     614#define IIR_NUM_COEFFICIENTS                            (3)     // Assumed biquads 
     615 
     616static void iir_update (AudioOutputUtil::IIR &instance) 
     617{ 
     618        // Clear the filter state 
     619    bzero(&instance.state.x_mem[0], IIR_NUM_COEFFICIENTS * sizeof(float)); 
     620    bzero(&instance.state.y_mem[0], IIR_NUM_COEFFICIENTS * sizeof(float)); 
     621     
     622    memcpy(&instance.state.b[0], &instance.parameters.b[0], 
     623           IIR_NUM_COEFFICIENTS * sizeof(float)); 
     624    memcpy(&instance.state.a[0], &instance.parameters.a[0], 
     625           IIR_NUM_COEFFICIENTS * sizeof(float)); 
     626} 
     627 
     628/* Notch filter (c) 2010 Hydrix & Jean-Yves Avenard */ 
     629/* www.hydrix.com */ 
     630 
     631// Processes a single block of samples with a single IIR biquad stage 
     632//    N                   M 
     633//   SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k)      for 1<=n<=length(x) 
     634//   k=0                 k=0 
     635// where N=length(a)-1 and M=length(b)-1. 
     636// Vector s is the initial state of the system. The final state is also returned 
     637// The state vector is a column vector whose length is equal to the 
     638//      length of the longest coefficient vector minus one. 
     639static void iir_biquad (float* x, float* y, 
     640                        float* a, float* b, 
     641                        float* x_mem, float* y_mem, 
     642                        unsigned int N) 
     643{ 
     644   // Direct Form I 
     645   //               N+1               N+1 
     646   //           y(n) = - SUM a(k) y(n-k) + SUM b(k) x(n-k)  for 0 <= n <length(x) 
     647   //               k=1               k=0 
     648    unsigned int n = 0; 
     649    unsigned int k = 0; 
     650    float y_n_minus_k = 0.0f; 
     651    float x_n_minus_k = 0.0f; 
     652    for (n = 0; n < N; n++) 
     653    { 
     654        y[n] = x[n] * b[0]; 
     655 
     656        for (k = 1; k < IIR_NUM_COEFFICIENTS; k++) 
     657        { 
     658            signed int n_minus_k = n - k; 
     659            if (n_minus_k >= 0) 
     660            { 
     661                x_n_minus_k = x[n_minus_k]; 
     662                y_n_minus_k = y[n_minus_k]; 
     663            } 
     664            else 
     665            { 
     666                x_n_minus_k = x_mem[-n_minus_k-1]; 
     667                y_n_minus_k = y_mem[-n_minus_k-1]; 
     668            } 
     669 
     670            y[n] -= a[k] * y_n_minus_k; 
     671            y[n] += b[k] * x_n_minus_k; 
     672        } 
     673    } 
     674 
     675        // Save input and output state, latest first 
     676    unsigned int state_offset = N - 1; 
     677    for (n=0; n < (IIR_NUM_COEFFICIENTS-1); n++) 
     678    { 
     679        x_mem[n] = x[state_offset]; 
     680        y_mem[n] = y[state_offset]; 
     681        state_offset--; 
     682    } 
     683} 
     684 
     685static void iir_execute(AudioOutputUtil::IIR &instance, float* x, float* y) 
     686{ 
     687    iir_biquad(x, y, 
     688               &instance.state.a[0], &instance.state.b[0], 
     689               &instance.state.x_mem[0], &instance.state.y_mem[0], 
     690               instance.parameters.N); 
     691} 
     692 
     693// Notch filter 
     694#define PI_FLOAT                    (3.14159265358979f) 
     695 
     696void AudioOutputUtil::notch_update (Notch &instance, float fs) 
     697{ 
     698    instance.state.pole_position = 0.99f; 
     699    instance.state.frequency_offset = 0.0f; // in normalised frequency (1.0 = fs) 
     700    instance.state.a1s = -instance.state.pole_position; 
     701    instance.state.a2 = -(instance.state.pole_position * instance.state.pole_position); 
     702    instance.state.depth_factor = 1.0f; 
     703 
     704        // Calculate filter coefficients 
     705        // Direct-form IIR 
     706        // Ref: http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt and others 
     707    float normalised_notch_frequency = (2.0f * instance.parameters.frequency / fs); 
     708    normalised_notch_frequency += instance.state.frequency_offset; 
     709    float frequency_factor = -2.0f * cosf(PI_FLOAT * normalised_notch_frequency); 
     710    float a1 = frequency_factor * instance.state.a1s; 
     711    float a2 = instance.state.a2; 
     712    float b1 = frequency_factor * instance.state.depth_factor; 
     713    float b2 = instance.state.depth_factor * instance.state.depth_factor; 
     714    instance.iir.parameters.N = instance.parameters.N; 
     715    instance.iir.parameters.a[0] = 1.0f; 
     716    instance.iir.parameters.a[1] = -a1; 
     717    instance.iir.parameters.a[2] = -a2; 
     718    instance.iir.parameters.b[0] = 1.0f; 
     719    instance.iir.parameters.b[1] = b1; 
     720    instance.iir.parameters.b[2] = b2; 
     721 
     722        // Initialise the IIR stage 
     723    iir_update(instance.iir); 
     724} 
     725 
     726// Processes a single block of samples 
     727void AudioOutputUtil::notch_execute (Notch &instance, float *in, float *out) 
     728{ 
     729    // Apply the rejection filter 
     730    iir_execute(instance.iir, in, out); 
     731} 
  • mythtv/programs/mythfrontend/globalsettings.cpp

     
    219219    return gc; 
    220220} 
    221221 
     222static HostCheckBox *VuvuzelaFilter() 
     223{ 
     224    HostCheckBox *gc = new HostCheckBox("VuvuzelaFilter"); 
     225    gc->setLabel(QObject::tr("Enable vuvuzela filter")); 
     226    gc->setValue(false); 
     227    gc->setHelpText(QObject::tr("With this option enabled, a dedicated vuvuzela " 
     228                                "filter option will be accessible in the playback " 
     229                                "menu")); 
     230    return gc; 
     231} 
     232 
    222233static HostCheckBox *MythControlsVolume() 
    223234{ 
    224235    HostCheckBox *gc = new HostCheckBox("MythControlsVolume"); 
     
    33013312    settings4->addChild(srcqualityoverride); 
    33023313    settings4->addChild(sub4); 
    33033314 
     3315    group2->addChild(VuvuzelaFilter()); 
    33043316    group2->addChild(settings4); 
    33053317    group2->addChild(Audio48kOverride()); 
    33063318    group2->addChild(settings3); 
  • mythtv/programs/mythtranscode/transcode.cpp

     
    186186        // Do nothing 
    187187        return false; 
    188188    } 
    189  
     189    virtual bool ToggleVuvuzela(void) 
     190    { 
     191        // Do nothing 
     192        return false; 
     193    } 
     194    virtual bool IsVuvuzela(void) 
     195    { 
     196        // Do nothing 
     197        return false; 
     198    } 
    190199    virtual void SetSWVolume(int new_volume, bool save) 
    191200    { 
    192201        // Do nothing