Ticket #4804: libs_libmyth-preamp-patch-ticket-4804.patch
File libs_libmyth-preamp-patch-ticket-4804.patch, 7.4 KB (added by , 16 years ago) |
---|
-
libs/libmyth/audiooutput.h
Ticket 4804 is an enhancement to MythTV to provide a pre-amp feature. This is From: Erik Hovland <erik@hovland.org> the first step towards having native ReplayGain support in MythMusic. --- libs/libmyth/audiooutput.h | 15 +++++ libs/libmyth/audiooutputbase.cpp | 122 ++++++++++++++++++++++++++++++++++++++ libs/libmyth/audiooutputbase.h | 22 +++++++ 3 files changed, 157 insertions(+), 2 deletions(-) diff --git a/libs/libmyth/audiooutput.h b/libs/libmyth/audiooutput.h index 7b7901f..10b4cec 100644
a b class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners 31 31 virtual void SetStretchFactor(float factor); 32 32 virtual float GetStretchFactor(void) const { return 1.0f; } 33 33 34 // For software pre-amplification. 35 virtual bool IsPreAmpEnabled() const { return false; } 36 virtual void SetPreAmp(bool enabled) { return; } 37 virtual void EnablePreAmp() { return; } 38 virtual void DisablePreAmp() { return; } 39 virtual void SetPreAmpGain(float gain) { return; } 40 virtual void SetPreAmpFactor(float factor) { return; } 41 virtual float GetPreAmpGain() const { return 0.0; } 42 virtual float GetPreAmpFactor() const { return 1.0; } 43 virtual void ResetClippingMonitor() { return; } 44 virtual bool HasClippingOccurred() const { return false; } 45 virtual float GetMaxOutput() const { return 1.0; } 46 virtual float GetMaxClipFreePreAmpGain() const { return 0.0; } 47 virtual float GetMaxClipFreePreAmpFactor() const { return 1.0; } 48 34 49 // do AddSamples calls block? 35 50 virtual void SetBlocking(bool blocking) = 0; 36 51 -
libs/libmyth/audiooutputbase.cpp
diff --git a/libs/libmyth/audiooutputbase.cpp b/libs/libmyth/audiooutputbase.cpp index 1135016..d6a63f1 100644
a b 1 1 // Std C headers 2 2 #include <cmath> 3 #include <climits> 4 #include <cfloat> 3 5 4 6 // POSIX headers 5 7 #include <pthread.h> … … AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 46 48 need_resampler(false), 47 49 48 50 src_ctx(NULL), 51 52 pre_amp_enabled(false), pre_amp_factor(1.0), 53 pre_amp_max_output(0.0), 49 54 50 55 pSoundStretch(NULL), 51 56 encoder(NULL), … … bool AudioOutputBase::AddSamples(char *buffers[], int samples, 750 755 return true; 751 756 } 752 757 758 #define __APPLY_PRE_AMP(TYPE,MIN,MAX) \ 759 { \ 760 TYPE *buf = (TYPE *)buffer; \ 761 for ( int i = 0; i < samples; ++i ) \ 762 { \ 763 float f = (float)buf[i] / (float)MAX; \ 764 f *= pre_amp_factor; \ 765 float a = abs(f); \ 766 if ( a > pre_amp_max_output ) pre_amp_max_output = a; \ 767 if ( f >= 1.0 ) buf[i] = MAX; \ 768 else if ( f <= -1.0 ) buf[i] = MIN; \ 769 else buf[i] = (TYPE)round(f*MAX); \ 770 } \ 771 } 772 773 void AudioOutputBase::ApplyPreAmp(void *buffer, int samples, int sample_bytes) 774 { 775 if ( !pre_amp_enabled ) return; 776 // NOTE: This only handles 1, 2 or 4 byte samples. 777 if ( sample_bytes == 4 ) 778 __APPLY_PRE_AMP(int,INT_MIN,INT_MAX) 779 else if ( sample_bytes == 2 ) 780 __APPLY_PRE_AMP(short,SHRT_MIN,SHRT_MAX) 781 else if ( sample_bytes == 1 ) 782 __APPLY_PRE_AMP(char,CHAR_MIN,CHAR_MAX) 783 784 return; 785 } 786 #undef __APPLY_PRE_AMP 787 753 788 bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 754 789 { 755 790 // NOTE: This function is not threadsafe … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 860 895 int audio_bytes = audio_bits / 8; 861 896 int org_waud = waud; 862 897 898 if ( interleaved ) 899 // Apply to the single buffer if we're interleaved. 900 ApplyPreAmp(buffer,samples*source_audio_channels,audio_bytes); 901 else 902 { 903 // Otherwise, apply to each channel individually. 904 void **bufs = (void**)buffer; 905 for ( int i = 0; i < source_audio_channels; ++i ) 906 ApplyPreAmp(bufs[i],samples,audio_bytes); 907 } 908 863 909 int afree = audiofree(false); 864 910 865 911 int abps = (encoder) ? … … int AudioOutputBase::readOutputData(unsigned char*, int) 1350 1396 return 0; 1351 1397 } 1352 1398 1353 /* vim: set expandtab tabstop=4 shiftwidth=4: */ 1399 bool AudioOutputBase::IsPreAmpEnabled() const 1400 { 1401 return pre_amp_enabled; 1402 } 1354 1403 1404 void AudioOutputBase::SetPreAmp(bool enabled) 1405 { 1406 pre_amp_enabled = enabled; 1407 return; 1408 } 1409 1410 void AudioOutputBase::EnablePreAmp() 1411 { 1412 pre_amp_enabled = true; 1413 return; 1414 } 1415 1416 void AudioOutputBase::DisablePreAmp() 1417 { 1418 pre_amp_enabled = false; 1419 return; 1420 } 1421 1422 void AudioOutputBase::SetPreAmpGain(float gain) 1423 { 1424 pre_amp_factor = pow(10.0,gain/20.0); 1425 return; 1426 } 1427 1428 void AudioOutputBase::SetPreAmpFactor(float factor) 1429 { 1430 if ( factor >= 0 ) pre_amp_factor = factor; 1431 return; 1432 } 1433 1434 float AudioOutputBase::GetPreAmpGain() const 1435 { 1436 if ( pre_amp_factor <= 0 ) return -1.0*FLT_MAX; 1437 return 20.0*log(pre_amp_factor)/log(10.0); 1438 } 1439 1440 float AudioOutputBase::GetPreAmpFactor() const 1441 { 1442 return pre_amp_factor; 1443 } 1444 1445 void AudioOutputBase::ResetClippingMonitor() 1446 { 1447 pre_amp_max_output = 0.0; 1448 return; 1449 } 1450 1451 bool AudioOutputBase::HasClippingOccurred() const 1452 { 1453 return pre_amp_max_output > 1.0; 1454 } 1455 1456 float AudioOutputBase::GetMaxOutput() const 1457 { 1458 return pre_amp_max_output; 1459 } 1460 1461 float AudioOutputBase::GetMaxClipFreePreAmpGain() const 1462 { 1463 float max_factor = GetMaxClipFreePreAmpFactor(); 1464 if ( max_factor <= 0 ) return -1.0*FLT_MAX; 1465 return 20.0*log(max_factor)/log(10.0); 1466 } 1467 1468 float AudioOutputBase::GetMaxClipFreePreAmpFactor() const 1469 { 1470 if ( pre_amp_max_output == 0 ) return FLT_MAX; 1471 return pre_amp_factor / pre_amp_max_output; 1472 } 1473 1474 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmyth/audiooutputbase.h
diff --git a/libs/libmyth/audiooutputbase.h b/libs/libmyth/audiooutputbase.h index 4806d31..1662a56 100644
a b class AudioOutputBase : public AudioOutput 64 64 65 65 virtual void GetBufferStatus(uint &fill, uint &total) const; 66 66 67 // Only really used by the AudioOutputNULL object 67 // For software pre-amplification. 68 virtual bool IsPreAmpEnabled() const; 69 virtual void SetPreAmp(bool enabled); 70 virtual void EnablePreAmp(); 71 virtual void DisablePreAmp(); 72 virtual void SetPreAmpGain(float gain); 73 virtual void SetPreAmpFactor(float factor); 74 virtual float GetPreAmpGain() const; 75 virtual float GetPreAmpFactor() const; 76 virtual void ResetClippingMonitor(); 77 virtual bool HasClippingOccurred() const; 78 virtual float GetMaxOutput() const; 79 virtual float GetMaxClipFreePreAmpGain() const; 80 virtual float GetMaxClipFreePreAmpFactor() const; 68 81 82 // Only really used by the AudioOutputNULL object 69 83 virtual void bufferOutputData(bool y){ buffer_output_data_for_use = y; } 70 84 virtual int readOutputData(unsigned char *read_buffer, int max_length); 71 85 … … class AudioOutputBase : public AudioOutput 91 105 92 106 int GetAudioData(unsigned char *buffer, int buf_size, bool fill_buffer); 93 107 108 void ApplyPreAmp(void *buffer, int samples, int sample_bytes); 94 109 void _AddSamples(void *buffer, bool interleaved, int samples, long long timecode); 95 110 96 111 void OutputAudioLoop(void); … … class AudioOutputBase : public AudioOutput 144 159 bool need_resampler; 145 160 SRC_STATE *src_ctx; 146 161 162 // pre-amplification 163 bool pre_amp_enabled; 164 float pre_amp_factor; 165 float pre_amp_max_output; 166 147 167 // timestretch 148 168 soundtouch::SoundTouch *pSoundStretch; 149 169 AudioOutputDigitalEncoder *encoder;