Ticket #4804: preamp-r16313.patch
File preamp-r16313.patch, 6.6 KB (added by , 16 years ago) |
---|
-
audiooutputbase.h
50 50 int audio_samplerate, 51 51 bool audio_passthru, 52 52 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; 53 68 54 69 // do AddSamples calls block? 55 70 virtual void SetBlocking(bool blocking); … … 104 119 105 120 int GetAudioData(unsigned char *buffer, int buf_size, bool fill_buffer); 106 121 122 void ApplyPreAmp(void *buffer, int samples, int sample_bytes); 107 123 void _AddSamples(void *buffer, bool interleaved, int samples, long long timecode); 108 124 109 125 void KillAudio(); … … 161 177 float src_out[AUDIO_SRC_OUT_SIZE]; 162 178 short tmp_buff[AUDIO_TMP_BUF_SIZE]; 163 179 180 // pre-amplification 181 bool pre_amp_enabled; 182 float pre_amp_factor; 183 float pre_amp_max_output; 184 164 185 // timestretch 165 186 soundtouch::SoundTouch *pSoundStretch; 166 187 AudioOutputDigitalEncoder *encoder; -
audiooutputbase.cpp
2 2 #include <cstdio> 3 3 #include <cstdlib> 4 4 #include <cmath> 5 #include <climits> 6 #include <cfloat> 5 7 6 8 // POSIX headers 7 9 #include <pthread.h> … … 50 52 need_resampler(false), 51 53 52 54 src_ctx(NULL), 55 56 pre_amp_enabled(false), pre_amp_factor(1.0), 57 pre_amp_max_output(0.0), 53 58 54 59 pSoundStretch(NULL), 55 60 encoder(NULL), … … 846 851 return len; 847 852 } 848 853 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 } 868 void 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 849 882 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 850 883 long long timecode) 851 884 { … … 854 887 int len; // = samples * audio_bytes_per_sample; 855 888 int audio_bytes = audio_bits / 8; 856 889 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 858 902 int afree = audiofree(false); 859 903 860 904 int abps = (encoder) ? … … 1345 1389 return 0; 1346 1390 } 1347 1391 1392 bool AudioOutputBase::IsPreAmpEnabled() const 1393 { 1394 return pre_amp_enabled; 1395 } 1396 1397 void AudioOutputBase::SetPreAmp(bool enabled) 1398 { 1399 pre_amp_enabled = enabled; 1400 return; 1401 } 1402 1403 void AudioOutputBase::EnablePreAmp() 1404 { 1405 pre_amp_enabled = true; 1406 return; 1407 } 1408 1409 void AudioOutputBase::DisablePreAmp() 1410 { 1411 pre_amp_enabled = false; 1412 return; 1413 } 1414 1415 void AudioOutputBase::SetPreAmpGain(float gain) 1416 { 1417 pre_amp_factor = pow(10.0,gain/20.0); 1418 return; 1419 } 1420 1421 void AudioOutputBase::SetPreAmpFactor(float factor) 1422 { 1423 if ( factor >= 0 ) pre_amp_factor = factor; 1424 return; 1425 } 1426 1427 float 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 1433 float AudioOutputBase::GetPreAmpFactor() const 1434 { 1435 return pre_amp_factor; 1436 } 1437 1438 void AudioOutputBase::ResetClippingMonitor() 1439 { 1440 pre_amp_max_output = 0.0; 1441 return; 1442 } 1443 1444 bool AudioOutputBase::HasClippingOccurred() const 1445 { 1446 return pre_amp_max_output > 1.0; 1447 } 1448 1449 float AudioOutputBase::GetMaxOutput() const 1450 { 1451 return pre_amp_max_output; 1452 } 1453 1454 float 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 1461 float 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 1348 1467 /* vim: set expandtab tabstop=4 shiftwidth=4: */ 1349 -
audiooutput.h
36 36 int audio_samplerate, 37 37 bool audio_passthru, 38 38 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; } 39 54 40 55 virtual void SetStretchFactor(float factor); 41 56 virtual float GetStretchFactor(void) { return 1.0f; }