Ticket #8568: vuvuzela-fixes.patch
File vuvuzela-fixes.patch, 21.6 KB (added by , 14 years ago) |
---|
-
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
5134 5134 return false; 5135 5135 } 5136 5136 5137 bool 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 5147 bool NuppelVideoPlayer::IsVuvuzela() 5148 { 5149 return audioOutput ? audioOutput->IsVuvuzela() : false; 5150 } 5151 5137 5152 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5138 5153 { 5139 5154 if (videoOutput) -
mythtv/libs/libmythtv/avformatdecoder.cpp
4639 4639 else if (ctx->codec_id == CODEC_ID_DTS) 4640 4640 passthru = allow_dts_passthru && !internal_vol; 4641 4641 4642 passthru &= !GetNVP()->IsVuvuzela(); 4642 4643 passthru &= !transcoding && !disable_passthru; 4643 4644 // Don't know any cards that support spdif clocked at < 44100 4644 4645 // Some US cable transmissions have 2ch 32k AC-3 streams -
mythtv/libs/libmythtv/tv_play.h
436 436 const QStringList &actions); 437 437 438 438 void ToggleUpmix(PlayerContext*); 439 void ToggleVuvuzela(PlayerContext*); 439 440 void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true); 440 441 bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions); 441 442 -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
165 165 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 166 166 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 167 167 bool ToggleUpmix(void); 168 bool ToggleVuvuzela(void); 169 bool IsVuvuzela(void); 168 170 169 171 // Gets 170 172 QSize GetVideoBufferSize(void) const { return video_dim; } -
mythtv/libs/libmythtv/tv_play.cpp
4516 4516 ToggleTimeStretch(ctx); 4517 4517 else if (has_action("TOGGLEUPMIX", actions)) 4518 4518 ToggleUpmix(ctx); 4519 else if (has_action("TOGGLEVUVUZELA", actions)) 4520 ToggleVuvuzela(ctx); 4519 4521 else if (has_action("TOGGLESLEEP", actions)) 4520 4522 ToggleSleepTimer(ctx); 4521 4523 else if (has_action("TOGGLERECORD", actions) && islivetv) … … 8286 8288 ctx->nvp->GetOSD()->SetSettingsText(text, 5); 8287 8289 } 8288 8290 8291 void 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 8289 8305 // dir in 10ms jumps 8290 8306 void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit) 8291 8307 { … … 9949 9965 ToggleTimeStretch(actx); 9950 9966 else if (action == "TOGGLEUPMIX") 9951 9967 ToggleUpmix(actx); 9968 else if (action == "TOGGLEVUVUZELA") 9969 ToggleVuvuzela(actx); 9952 9970 else if (action.left(13) == "ADJUSTSTRETCH") 9953 9971 { 9954 9972 bool floatRead; … … 10323 10341 new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC"); 10324 10342 else if (category == "TOGGLEUPMIX") 10325 10343 new OSDGenericTree(treeMenu, tr("Toggle Audio Upmixer"), "TOGGLEUPMIX"); 10344 else if (category == "TOGGLEVUVUZELA") 10345 new OSDGenericTree(treeMenu, tr("Toggle Vuvuzela Filter"), "TOGGLEVUVUZELA"); 10326 10346 else if (category == "TIMESTRETCH") 10327 10347 FillMenuTimeStretch(ctx, treeMenu); 10328 10348 else if (category == "VIDEOSCAN") -
mythtv/libs/libmythtv/tvosdmenuentry.cpp
236 236 "AUDIOSYNC", 1, 1, 1, 1, "Audio Sync")); 237 237 curMenuEntries.append(new TVOSDMenuEntry( 238 238 "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 } 239 245 curMenuEntries.append(new TVOSDMenuEntry( 240 246 "TIMESTRETCH", 1, 1, 1, 1, "Time Stretch")); 241 247 curMenuEntries.append(new TVOSDMenuEntry( -
mythtv/libs/libmyth/audiooutputbase.h
16 16 17 17 // MythTV headers 18 18 #include "audiooutput.h" 19 #include "audiooutpututil.h" 19 20 #include "samplerate.h" 20 21 #include "mythverbose.h" 21 22 … … 44 45 virtual void SetStretchFactor(float factor); 45 46 virtual float GetStretchFactor(void) const; 46 47 virtual bool ToggleUpmix(void); 48 virtual bool ToggleVuvuzela(void); 49 virtual bool IsVuvuzela(void) { return vuvuzela; } 47 50 48 51 virtual void Reset(void); 49 52 … … 230 233 /** main audio buffer */ 231 234 unsigned char audiobuffer[kAudioRingBufferSize]; 232 235 uint memory_corruption_test4; 236 237 //Vuvuzela filter 238 bool vuvuzela, last_vuvuzela; 239 AudioOutputUtil::Notch *notch_instance; 233 240 }; 234 241 235 242 #endif -
mythtv/libs/libmyth/audiooutpututil.h
1 #ifndef AUDIOOUTPUTUTIL 2 #define AUDIOOUTPUTUTIL 3 4 using namespace std; 5 6 #define IIR_NUM_COEFFICIENTS (3) // Assumed biquads 7 8 class 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
13 13 #include "compat.h" 14 14 #include "audiooutputbase.h" 15 15 #include "audiooutputdigitalencoder.h" 16 #include "audiooutpututil.h" 16 17 #include "SoundTouch.h" 17 18 #include "freesurround.h" 18 19 … … 73 74 memory_corruption_test1(0xdeadbeef), 74 75 memory_corruption_test2(0xdeadbeef), 75 76 memory_corruption_test3(0xdeadbeef), 76 memory_corruption_test4(0xdeadbeef) 77 memory_corruption_test4(0xdeadbeef), 78 vuvuzela(false), last_vuvuzela(false), 79 notch_instance(NULL) 77 80 { 78 81 // The following are not bzero() because MS Windows doesn't like it. 79 82 memset(&src_data, 0, sizeof(SRC_DATA)); … … 197 200 return (configured_audio_channels == 6); 198 201 } 199 202 203 bool 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); 200 210 211 return vuvuzela; 212 } 213 201 214 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 202 215 { 203 216 AudioSettings settings = orig_settings; … … 229 242 settings.samplerate == audio_samplerate && !need_resampler && 230 243 settings.use_passthru == audio_passthru && 231 244 lneeds_upmix == needs_upmix && 245 last_vuvuzela == vuvuzela && 232 246 laudio_reenc == audio_reenc); 233 247 bool upmix_deps = 234 248 (lsource_audio_channels == source_audio_channels); … … 247 261 return; 248 262 } 249 263 264 last_vuvuzela = vuvuzela; 265 250 266 KillAudio(); 251 267 252 268 QMutexLocker lock1(&audio_buflock); … … 264 280 audio_codec = settings.codec; 265 281 audio_passthru = settings.use_passthru; 266 282 needs_upmix = lneeds_upmix; 283 vuvuzela = last_vuvuzela; 267 284 268 285 if (audio_bits != 8 && audio_bits != 16) 269 286 { … … 341 358 need_resampler = true; 342 359 } 343 360 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 344 368 if (audio_enc) 345 369 { 346 370 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); … … 497 521 needs_upmix = false; 498 522 audio_enc = false; 499 523 524 if (notch_instance) 525 { 526 delete notch_instance; 527 notch_instance = NULL; 528 } 529 vuvuzela = false; 530 500 531 CloseDevice(); 501 532 502 533 killAudioLock.unlock(); … … 790 821 VERBOSE(VB_IMPORTANT, LOC_ERR + 791 822 QString("Error occurred while resampling audio: %1") 792 823 .arg(src_strerror(error))); 793 794 824 src_float_to_short_array(src_data.data_out, (short int*)tmp_buff, 795 825 src_data.output_frames_gen*audio_channels); 796 826 … … 844 874 QMutexLocker lock1(&audio_buflock); 845 875 846 876 // resample input if necessary 847 if ( need_resampler && src_ctx)877 if ((need_resampler && src_ctx) || (vuvuzela && notch_instance)) 848 878 { 849 879 // Convert to floats 850 880 short *buf_ptr = (short*)buffer; … … 853 883 src_in[sample] = (float)buf_ptr[sample] / (1.0 * 0x8000); 854 884 } 855 885 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 } 865 906 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 } 867 927 } 868 928 else 869 929 { -
mythtv/libs/libmyth/libmyth.pro
30 30 HEADERS += audiopulseutil.h 31 31 HEADERS += programinfo.h programlist.h programinfoupdater.h 32 32 HEADERS += recordingtypes.h remoteutil.h 33 HEADERS += rawsettingseditor.h 33 HEADERS += rawsettingseditor.h audiooutpututil.h 34 34 35 35 # remove when everything is switched to mythui 36 36 HEADERS += virtualkeyboard_qt.h … … 54 54 SOURCES += audiopulseutil.cpp 55 55 SOURCES += programinfo.cpp programlist.cpp programinfoupdater.cpp 56 56 SOURCES += recordingtypes.cpp remoteutil.cpp 57 SOURCES += rawsettingseditor.cpp 57 SOURCES += rawsettingseditor.cpp audiooutpututil.cpp 58 58 59 59 # remove when everything is switched to mythui 60 60 SOURCES += virtualkeyboard_qt.cpp -
mythtv/libs/libmyth/audiooutput.h
71 71 virtual void bufferOutputData(bool y) = 0; 72 72 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 73 73 virtual bool ToggleUpmix(void) = 0; 74 virtual bool ToggleVuvuzela(void) = 0; 75 virtual bool IsVuvuzela(void) = 0; 74 76 75 77 protected: 76 78 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 7 static 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. 30 static 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 76 static 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 87 void 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 131 void 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
181 181 return gc; 182 182 } 183 183 184 static 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 184 195 static HostCheckBox *MythControlsVolume() 185 196 { 186 197 HostCheckBox *gc = new HostCheckBox("MythControlsVolume"); … … 3485 3496 settings2->addChild(srcqualityoverride); 3486 3497 settings2->addChild(sub3); 3487 3498 3499 group2->addChild(VuvuzelaFilter()); 3488 3500 group2->addChild(settings2); 3489 3501 group2->addChild(AggressiveBuffer()); 3490 3502 -
mythtv/programs/mythtranscode/transcode.cpp
217 217 // Do nothing 218 218 return false; 219 219 } 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 } 221 230 virtual void SetSWVolume(int new_volume, bool save) 222 231 { 223 232 // Do nothing