Ticket #1104: mythtv_ac3.44.patch
File mythtv_ac3.44.patch, 59.6 KB (added by , 16 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.cpp
206 206 audio_passthru_device(QString::null), 207 207 audio_channels(2), audio_bits(-1), 208 208 audio_samplerate(44100), audio_stretchfactor(1.0f), 209 audio_codec(NULL), 209 210 // Picture-in-Picture 210 211 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 211 212 // Preview window support … … 767 768 if (audioOutput) 768 769 { 769 770 audioOutput->Reconfigure(audio_bits, audio_channels, 770 audio_samplerate, audio_passthru); 771 audio_samplerate, audio_passthru, 772 audio_codec); 771 773 errMsg = audioOutput->GetError(); 772 774 if (!errMsg.isEmpty()) 773 775 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3650 3652 audio_passthru = passthru; 3651 3653 } 3652 3654 3655 void NuppelVideoPlayer::SetAudioCodec(void *ac) 3656 { 3657 audio_codec = ac; 3658 } 3659 3653 3660 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3654 3661 { 3655 3662 if (audioOutput) -
libs/libmythtv/avformatdecoder.cpp
51 51 52 52 #define MAX_AC3_FRAME_SIZE 6144 53 53 54 /** Set to zero to allow any number of AC3 channels. */55 #define MAX_OUTPUT_CHANNELS 256 57 54 static int cc608_parity(uint8_t byte); 58 55 static int cc608_good_parity(const int *parity_table, uint16_t data); 59 56 static void cc608_build_parity_table(int *parity_table); … … 400 397 // Audio 401 398 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 402 399 allow_ac3_passthru(false), allow_dts_passthru(false), 403 disable_passthru(false), dummy_frame(NULL), 400 disable_passthru(false), max_channels(2), 401 dummy_frame(NULL), 404 402 // DVD 405 403 lastdvdtitle(-1), lastcellstart(0), 406 404 dvdmenupktseen(false), indvdstill(false), … … 417 415 418 416 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 419 417 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 418 max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2); 420 419 421 420 audioIn.sample_size = -32; // force SetupAudioStream to run once 422 421 itv = GetNVP()->GetInteractiveTV(); … … 1587 1586 <<") already open, leaving it alone."); 1588 1587 } 1589 1588 //assert(enc->codec_id); 1589 VERBOSE(VB_GENERAL, LOC + QString("codec %1 has %2 channels") 1590 .arg(codec_id_string(enc->codec_id)) 1591 .arg(enc->channels)); 1590 1592 1593 #if 0 1594 // HACK MULTICHANNEL DTS passthru disabled for multichannel, 1595 // dont know how to handle this 1591 1596 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1592 1597 if (enc->codec_id == CODEC_ID_DTS) 1593 1598 { … … 1596 1601 // enc->bit_rate = what??; 1597 1602 } 1598 1603 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1604 #endif 1599 1605 1600 1606 bitrate += enc->bit_rate; 1601 1607 break; … … 3288 3294 if (!curstream->codec->channels) 3289 3295 { 3290 3296 QMutexLocker locker(&avcodeclock); 3291 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 3297 VERBOSE(VB_IMPORTANT, LOC + 3298 QString("Setting channels to %1") 3299 .arg(audioOut.channels)); 3300 3301 curstream->codec->channels = audioOut.channels; 3292 3302 ret = avcodec_decode_audio( 3293 3303 curstream->codec, audioSamples, 3294 3304 &data_size, ptr, len); … … 3349 3359 AVCodecContext *ctx = curstream->codec; 3350 3360 3351 3361 if ((ctx->channels == 0) || 3352 (ctx->channels > MAX_OUTPUT_CHANNELS))3353 ctx->channels = MAX_OUTPUT_CHANNELS;3362 (ctx->channels > audioOut.channels)) 3363 ctx->channels = audioOut.channels; 3354 3364 3355 3365 ret = avcodec_decode_audio( 3356 3366 ctx, audioSamples, &data_size, ptr, len); … … 3783 3793 3784 3794 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3785 3795 { 3796 // can only disable never reenable as once 3797 // timestretch is on its on for the session 3798 if (disable_passthru) 3799 return; 3800 3786 3801 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3787 3802 { 3788 3803 disable_passthru = disable; … … 3815 3830 AVCodecContext *codec_ctx = NULL; 3816 3831 AudioInfo old_in = audioIn; 3817 3832 AudioInfo old_out = audioOut; 3833 bool using_passthru = false; 3818 3834 3819 3835 if ((currentTrack[kTrackTypeAudio] >= 0) && 3820 3836 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3826 3842 assert(curstream->codec); 3827 3843 codec_ctx = curstream->codec; 3828 3844 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3829 !disable_passthru &&3830 3845 (codec_ctx->codec_id == CODEC_ID_AC3)); 3831 3846 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3832 !disable_passthru &&3833 3847 (codec_ctx->codec_id == CODEC_ID_DTS)); 3848 using_passthru = do_ac3_passthru || do_dts_passthru; 3834 3849 info = AudioInfo(codec_ctx->codec_id, 3835 3850 codec_ctx->sample_rate, codec_ctx->channels, 3836 do_ac3_passthru || do_dts_passthru);3851 using_passthru && !disable_passthru); 3837 3852 } 3838 3853 3839 3854 if (info == audioIn) 3840 3855 return false; // no change 3841 3856 3857 QString ptmsg = (using_passthru) ? " using passthru" : ""; 3842 3858 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3843 3859 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3844 3860 3845 3861 audioOut = audioIn = info; 3846 if ( audioIn.do_passthru)3862 if (using_passthru) 3847 3863 { 3848 3864 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3849 audioOut.channels = 2; 3850 audioOut.sample_rate = 48000; 3851 audioOut.sample_size = 4; 3865 AudioInfo digInfo = audioOut; 3866 if (!disable_passthru) 3867 { 3868 digInfo.channels = 2; 3869 digInfo.sample_rate = 48000; 3870 digInfo.sample_size = 4; 3871 } 3872 if (audioOut.channels > (int) max_channels) 3873 { 3874 audioOut.channels = (int) max_channels; 3875 audioOut.sample_size = audioOut.channels * 2; 3876 codec_ctx->channels = audioOut.channels; 3877 } 3878 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3879 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3880 .arg(digInfo.toString()) 3881 .arg(old_in.toString()).arg(old_out.toString()) 3882 .arg(audioIn.toString()).arg(audioOut.toString())); 3883 3884 if (digInfo.sample_rate > 0) 3885 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3886 3887 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3888 digInfo.sample_rate, audioIn.do_passthru); 3889 // allow the audio stuff to reencode 3890 GetNVP()->SetAudioCodec(codec_ctx); 3891 GetNVP()->ReinitAudio(); 3892 return true; 3852 3893 } 3853 3894 else 3854 3895 { 3855 if (audioOut.channels > MAX_OUTPUT_CHANNELS)3896 if (audioOut.channels > (int) max_channels) 3856 3897 { 3857 audioOut.channels = MAX_OUTPUT_CHANNELS;3898 audioOut.channels = (int) max_channels; 3858 3899 audioOut.sample_size = audioOut.channels * 2; 3859 codec_ctx->channels = MAX_OUTPUT_CHANNELS;3900 codec_ctx->channels = audioOut.channels; 3860 3901 } 3861 3902 } 3862 3903 … … 3871 3912 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3872 3913 audioOut.sample_rate, 3873 3914 audioIn.do_passthru); 3874 GetNVP()->ReinitAudio();3875 3915 3916 // allow the audio stuff to reencode 3917 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3918 QString errMsg = GetNVP()->ReinitAudio(); 3919 bool audiook = errMsg.isEmpty(); 3920 3876 3921 return true; 3877 3922 } 3878 3923 -
libs/libmythtv/NuppelVideoPlayer.h
127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 void SetAudioCodec(void *ac); 130 131 131 132 // Sets 132 133 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 683 684 int audio_bits; 684 685 int audio_samplerate; 685 686 float audio_stretchfactor; 687 void *audio_codec; 686 688 bool audio_passthru; 687 689 688 690 // Picture-in-Picture -
libs/libmythtv/avformatdecoder.h
261 261 bool allow_ac3_passthru; 262 262 bool allow_dts_passthru; 263 263 bool disable_passthru; 264 uint max_channels; 265 264 266 VideoFrame *dummy_frame; 265 267 266 268 AudioInfo audioIn; -
libs/libs.pro
6 6 # Directories 7 7 SUBDIRS += libavutil libavcodec libavformat libmythsamplerate 8 8 SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav 9 SUBDIRS += libmythfreesurround 9 10 10 11 mingw : SUBDIRS += libmyth libmythupnp libmythui 11 12 !mingw: SUBDIRS += libmythupnp libmythui libmyth -
libs/libavcodec/liba52.c
134 134 } 135 135 } 136 136 137 static inline int16_t convert(int32_t i) 138 { 139 return av_clip_int16(i - 0x43c00000); 140 } 141 142 void float2s16_2 (float * _f, int16_t * s16) 143 { 144 int i; 145 int32_t * f = (int32_t *) _f; 146 147 for (i = 0; i < 256; i++) { 148 s16[2*i] = convert (f[i]); 149 s16[2*i+1] = convert (f[i+256]); 150 } 151 } 152 153 void float2s16_4 (float * _f, int16_t * s16) 154 { 155 int i; 156 int32_t * f = (int32_t *) _f; 157 158 for (i = 0; i < 256; i++) { 159 s16[4*i] = convert (f[i]); 160 s16[4*i+1] = convert (f[i+256]); 161 s16[4*i+2] = convert (f[i+512]); 162 s16[4*i+3] = convert (f[i+768]); 163 } 164 } 165 166 void float2s16_5 (float * _f, int16_t * s16) 167 { 168 int i; 169 int32_t * f = (int32_t *) _f; 170 171 for (i = 0; i < 256; i++) { 172 s16[5*i] = convert (f[i]); 173 s16[5*i+1] = convert (f[i+256]); 174 s16[5*i+2] = convert (f[i+512]); 175 s16[5*i+3] = convert (f[i+768]); 176 s16[5*i+4] = convert (f[i+1024]); 177 } 178 } 179 180 #define LIKEAC3DEC 1 181 int channels_multi (int flags) 182 { 183 if (flags & A52_LFE) 184 return 6; 185 else if (flags & 1) /* center channel */ 186 return 5; 187 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 188 return 4; 189 else 190 return 2; 191 } 192 193 void float2s16_multi (float * _f, int16_t * s16, int flags) 194 { 195 int i; 196 int32_t * f = (int32_t *) _f; 197 198 switch (flags) { 199 case A52_MONO: 200 for (i = 0; i < 256; i++) { 201 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 202 s16[5*i+4] = convert (f[i]); 203 } 204 break; 205 case A52_CHANNEL: 206 case A52_STEREO: 207 case A52_DOLBY: 208 float2s16_2 (_f, s16); 209 break; 210 case A52_3F: 211 for (i = 0; i < 256; i++) { 212 s16[5*i] = convert (f[i]); 213 s16[5*i+1] = convert (f[i+512]); 214 s16[5*i+2] = s16[5*i+3] = 0; 215 s16[5*i+4] = convert (f[i+256]); 216 } 217 break; 218 case A52_2F2R: 219 float2s16_4 (_f, s16); 220 break; 221 case A52_3F2R: 222 float2s16_5 (_f, s16); 223 break; 224 case A52_MONO | A52_LFE: 225 for (i = 0; i < 256; i++) { 226 #if LIKEAC3DEC 227 s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 228 s16[6*i+1] = convert (f[i+256]); 229 s16[6*i+5] = convert (f[i]); 230 #else 231 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 232 s16[6*i+4] = convert (f[i+256]); 233 s16[6*i+5] = convert (f[i]); 234 #endif 235 } 236 break; 237 case A52_CHANNEL | A52_LFE: 238 case A52_STEREO | A52_LFE: 239 case A52_DOLBY | A52_LFE: 240 for (i = 0; i < 256; i++) { 241 #if LIKEAC3DEC 242 s16[6*i] = convert (f[i+256]); 243 s16[6*i+2] = convert (f[i+512]); 244 s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0; 245 s16[6*i+5] = convert (f[i]); 246 #else 247 s16[6*i] = convert (f[i+256]); 248 s16[6*i+1] = convert (f[i+512]); 249 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 250 s16[6*i+5] = convert (f[i]); 251 #endif 252 } 253 break; 254 case A52_3F | A52_LFE: 255 for (i = 0; i < 256; i++) { 256 #if LIKEAC3DEC 257 s16[6*i] = convert (f[i+256]); 258 s16[6*i+2] = convert (f[i+768]); 259 s16[6*i+3] = s16[6*i+4] = 0; 260 s16[6*i+1] = convert (f[i+512]); 261 s16[6*i+5] = convert (f[i]); 262 #else 263 s16[6*i] = convert (f[i+256]); 264 s16[6*i+1] = convert (f[i+768]); 265 s16[6*i+2] = s16[6*i+3] = 0; 266 s16[6*i+4] = convert (f[i+512]); 267 s16[6*i+5] = convert (f[i]); 268 #endif 269 } 270 break; 271 case A52_2F2R | A52_LFE: 272 for (i = 0; i < 256; i++) { 273 #if LIKEAC3DEC 274 s16[6*i] = convert (f[i+256]); 275 s16[6*i+1] = 0; 276 s16[6*i+2] = convert (f[i+512]); 277 s16[6*i+3] = convert (f[i+768]); 278 s16[6*i+4] = convert (f[i+1024]); 279 s16[6*i+5] = convert (f[i]); 280 #else 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+512]); 283 s16[6*i+2] = convert (f[i+768]); 284 s16[6*i+3] = convert (f[i+1024]); 285 s16[6*i+4] = 0; 286 s16[6*i+5] = convert (f[i]); 287 #endif 288 } 289 break; 290 case A52_3F2R | A52_LFE: 291 for (i = 0; i < 256; i++) { 292 #if LIKEAC3DEC 293 s16[6*i] = convert (f[i+256]); 294 s16[6*i+1] = convert (f[i+512]); 295 s16[6*i+2] = convert (f[i+768]); 296 s16[6*i+3] = convert (f[i+1024]); 297 s16[6*i+4] = convert (f[i+1280]); 298 s16[6*i+5] = convert (f[i]); 299 #else 300 s16[6*i] = convert (f[i+256]); 301 s16[6*i+1] = convert (f[i+768]); 302 s16[6*i+2] = convert (f[i+1024]); 303 s16[6*i+3] = convert (f[i+1280]); 304 s16[6*i+4] = convert (f[i+512]); 305 s16[6*i+5] = convert (f[i]); 306 #endif 307 } 308 break; 309 } 310 } 311 137 312 /**** end */ 138 313 139 314 #define HEADER_SIZE 7 … … 177 352 /* update codec info */ 178 353 avctx->sample_rate = sample_rate; 179 354 s->channels = ac3_channels[s->flags & 7]; 355 if (avctx->cqp >= 0) 356 avctx->channels = avctx->cqp; 180 357 if (s->flags & A52_LFE) 181 358 s->channels++; 182 359 if (avctx->channels == 0) … … 199 376 s->inbuf_ptr += len; 200 377 buf_size -= len; 201 378 } else { 379 int chans; 202 380 flags = s->flags; 203 381 if (avctx->channels == 1) 204 382 flags = A52_MONO; 205 else if (avctx->channels == 2) 206 flags = A52_STEREO; 383 else if (avctx->channels == 2) { 384 if (s->channels>2) 385 flags = A52_DOLBY; 386 else 387 flags = A52_STEREO; 388 } 207 389 else 208 390 flags |= A52_ADJUST_LEVEL; 209 391 level = 1; 392 chans = channels_multi(flags); 210 393 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 211 394 fail: 212 395 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 217 400 for (i = 0; i < 6; i++) { 218 401 if (s->a52_block(s->state)) 219 402 goto fail; 220 float _to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);403 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 221 404 } 222 405 s->inbuf_ptr = s->inbuf; 223 406 s->frame_size = 0; -
libs/libmyth/audiooutputbase.h
16 16 // MythTV headers 17 17 #include "audiooutput.h" 18 18 #include "samplerate.h" 19 #include "SoundTouch.h"20 19 21 #define AUDBUFSIZE 768000 20 namespace soundtouch { 21 class SoundTouch; 22 }; 23 class FreeSurround; 24 class AudioOutputDigitalEncoder; 25 struct AVCodecContext; 26 22 27 #define AUDIO_SRC_IN_SIZE 16384 23 28 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 29 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 30 31 //#define AUDBUFSIZE 768000 32 //divisible by 12,10,8,6,4,2 and around 1024000 33 //#define AUDBUFSIZE 1024080 34 #define AUDBUFSIZE 1536000 35 26 36 class AudioOutputBase : public AudioOutput 27 37 { 28 38 public: … … 35 45 virtual ~AudioOutputBase(); 36 46 37 47 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, 50 int audio_samplerate, 51 bool audio_passthru, 52 void* audio_codec = NULL); 40 53 41 54 // do AddSamples calls block? 42 55 virtual void SetBlocking(bool blocking); … … 45 58 virtual void SetEffDsp(int dsprate); 46 59 47 60 virtual void SetStretchFactor(float factor); 61 virtual float GetStretchFactor(void); 48 62 49 63 virtual void Reset(void); 50 64 … … 127 141 bool audio_passthru; 128 142 129 143 float audio_stretchfactor; 144 AVCodecContext *audio_codec; 130 145 AudioOutputSource source; 131 146 132 147 bool killaudio; … … 135 150 bool set_initial_vol; 136 151 bool buffer_output_data_for_use; // used by AudioOutputNULL 137 152 153 int configured_audio_channels; 154 138 155 private: 139 156 // resampler 140 157 bool need_resampler; … … 145 162 short tmp_buff[AUDIO_TMP_BUF_SIZE]; 146 163 147 164 // timestretch 148 soundtouch::SoundTouch * pSoundStretch; 165 soundtouch::SoundTouch *pSoundStretch; 166 AudioOutputDigitalEncoder *encoder; 167 FreeSurround *upmixer; 149 168 169 int source_audio_channels; 170 int source_audio_bytes_per_sample; 171 bool needs_upmix; 172 int surround_mode; 173 150 174 bool blocking; // do AddSamples calls block? 151 175 152 176 int lastaudiolen; … … 164 188 165 189 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 166 190 'audiotime' and 'audiotime_updated' */ 167 int audiotime; // timecode of audio leaving the soundcard (same units as168 // timecodes) ...191 /// timecode of audio leaving the soundcard (same units as timecodes) 192 long long audiotime; 169 193 struct timeval audiotime_updated; // ... which was last updated at this time 170 194 171 195 /* Audio circular buffer */ 172 196 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 173 197 int raud, waud; /* read and write positions */ 174 int audbuf_timecode; /* timecode of audio most recently placed into175 buffer */198 /// timecode of audio most recently placed into buffer 199 long long audbuf_timecode; 176 200 177 201 int numlowbuffer; 178 202 -
libs/libmyth/audiooutputalsa.cpp
52 52 QString real_device = (audio_passthru) ? 53 53 audio_passthru_device : audio_main_device; 54 54 55 int index = real_device.find('|'); 56 if (index >= 0) 57 { 58 if (audio_channels >= 2) 59 real_device = real_device.mid(index+1); 60 else 61 real_device = real_device.left(index); 62 } 63 55 64 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 65 .arg(real_device)); 57 66 … … 89 98 } 90 99 else 91 100 { 92 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 93 buffer_time = 500000; // .5 seconds 101 fragment_size = 102 (audio_bits * audio_channels * audio_samplerate) / (8*30); 103 buffer_time = 100000; 94 104 period_time = buffer_time / 4; // 4 interrupts per buffer 95 105 } 96 106 … … 162 172 163 173 tmpbuf = aubuf; 164 174 165 VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 175 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 176 QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 177 .arg(size).arg(frames)); 167 178 168 179 while (frames > 0) -
libs/libmyth/audiooutputbase.cpp
15 15 16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 #include "audiooutputdigitalencoder.h" 19 #include "SoundTouch.h" 20 #include "freesurround.h" 18 21 #include "compat.h" 19 22 20 23 #define LOC QString("AO: ") … … 36 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 37 40 audio_passthru(false), audio_stretchfactor(1.0f), 38 41 42 audio_codec(NULL), 39 43 source(lsource), killaudio(false), 40 44 41 45 pauseaudio(false), audio_actually_paused(false), … … 47 51 48 52 src_ctx(NULL), 49 53 50 pSoundStretch(NULL), blocking(false), 54 pSoundStretch(NULL), 55 encoder(NULL), 56 upmixer(NULL), 57 source_audio_channels(-1), 58 source_audio_bytes_per_sample(0), 59 needs_upmix(false), 60 surround_mode(FreeSurround::SurroundModePassive), 51 61 62 blocking(false), 63 52 64 lastaudiolen(0), samples_buffered(0), 53 65 54 66 audio_thread_exists(false), … … 71 83 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 84 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 85 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 86 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 87 75 88 // You need to call Reconfigure from your concrete class. 76 89 // Reconfigure(laudio_bits, laudio_channels, … … 111 124 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 125 .arg(audio_stretchfactor)); 113 126 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 127 if (audio_codec) 128 { 129 if (!encoder) 130 { 131 VERBOSE(VB_AUDIO, LOC + 132 QString("Creating Encoder for codec %1 origfs %2") 133 .arg(audio_codec->codec_id) 134 .arg(audio_codec->frame_size)); 116 135 136 encoder = new AudioOutputDigitalEncoder(); 137 if (!encoder->Init(audio_codec->codec_id, 138 audio_codec->bit_rate, 139 audio_codec->sample_rate, 140 audio_codec->channels 141 )) 142 { 143 // eeks 144 delete encoder; 145 encoder = NULL; 146 VERBOSE(VB_AUDIO, LOC + 147 QString("Failed to Create Encoder")); 148 } 149 } 150 } 151 if (encoder) 152 { 153 pSoundStretch->setSampleRate(audio_codec->sample_rate); 154 pSoundStretch->setChannels(audio_codec->channels); 155 } 156 else 157 { 158 pSoundStretch->setSampleRate(audio_samplerate); 159 pSoundStretch->setChannels(audio_channels); 160 } 161 117 162 pSoundStretch->setTempo(audio_stretchfactor); 118 163 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 119 164 … … 134 179 pthread_mutex_unlock(&audio_buflock); 135 180 } 136 181 182 float AudioOutputBase::GetStretchFactor() 183 { 184 return audio_stretchfactor; 185 } 186 137 187 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 188 int laudio_samplerate, bool laudio_passthru, 189 void* laudio_codec) 139 190 { 191 int codec_id = CODEC_ID_NONE; 192 int lcodec_id = CODEC_ID_NONE; 193 int lcchannels = 0; 194 int cchannels = 0; 195 int lsource_audio_channels = laudio_channels; 196 bool lneeds_upmix = false; 197 198 if (laudio_codec) 199 { 200 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 201 laudio_bits = 16; 202 laudio_channels = 2; 203 lsource_audio_channels = laudio_channels; 204 laudio_samplerate = 48000; 205 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 206 } 207 208 if (audio_codec) 209 { 210 codec_id = audio_codec->codec_id; 211 cchannels = ((AVCodecContext*)audio_codec)->channels; 212 } 213 214 if ((configured_audio_channels == 6) && 215 !(laudio_codec || audio_codec)) 216 { 217 laudio_channels = configured_audio_channels; 218 lneeds_upmix = true; 219 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 220 } 221 222 ClearError(); 223 140 224 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 225 laudio_samplerate == audio_samplerate && !need_resampler && 226 laudio_passthru == audio_passthru && 227 lneeds_upmix == needs_upmix && 228 lcodec_id == codec_id && lcchannels == cchannels) 229 { 230 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 231 return; 232 } 144 233 145 234 KillAudio(); 146 235 … … 151 240 waud = raud = 0; 152 241 audio_actually_paused = false; 153 242 243 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 244 audio_channels = laudio_channels; 245 source_audio_channels = lsource_audio_channels; 155 246 audio_bits = laudio_bits; 156 247 audio_samplerate = laudio_samplerate; 248 audio_codec = (AVCodecContext*)laudio_codec; 157 249 audio_passthru = laudio_passthru; 250 needs_upmix = lneeds_upmix; 251 158 252 if (audio_bits != 8 && audio_bits != 16) 159 253 { 160 254 pthread_mutex_unlock(&avsync_lock); … … 162 256 Error("AudioOutput only supports 8 or 16bit audio."); 163 257 return; 164 258 } 259 165 260 audio_bytes_per_sample = audio_channels * audio_bits / 8; 261 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 166 262 167 263 need_resampler = false; 168 264 killaudio = false; … … 172 268 173 269 numlowbuffer = 0; 174 270 271 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 272 .arg(audio_main_device).arg(audio_channels) 273 .arg(source_audio_channels).arg(audio_samplerate)); 274 175 275 // Actually do the device specific open call 176 276 if (!OpenDevice()) 177 277 { 178 278 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 279 pthread_mutex_unlock(&avsync_lock); 180 280 pthread_mutex_unlock(&audio_buflock); 281 if (GetError().isEmpty()) 282 Error("Aborting reconfigure"); 283 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 284 return; 182 285 } 183 286 … … 200 303 current_seconds = -1; 201 304 source_bitrate = -1; 202 305 306 // NOTE: this won't do anything as above samplerate vars are set equal 203 307 // Check if we need the resampler 204 308 if (audio_samplerate != laudio_samplerate) 205 309 { … … 222 326 need_resampler = true; 223 327 } 224 328 329 if (needs_upmix) 330 { 331 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 332 if (configured_audio_channels == 6) 333 { 334 surround_mode = gContext->GetNumSetting("AudioUpmixType", 2); 335 } 336 337 upmixer = new FreeSurround( 338 audio_samplerate, 339 source == AUDIOOUTPUT_VIDEO, 340 (FreeSurround::SurroundMode)surround_mode); 341 342 VERBOSE(VB_AUDIO, LOC + 343 QString("create upmixer done with surround mode %1") 344 .arg(surround_mode)); 345 } 346 225 347 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 348 .arg(audio_stretchfactor)); 349 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 350 .arg((audio_codec) ? 351 codec_id_string(audio_codec->codec_id) : "not set")); 227 352 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 353 if (redo_stretch) 230 354 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 355 float laudio_stretchfactor = audio_stretchfactor; 356 delete pSoundStretch; 357 pSoundStretch = NULL; 358 audio_stretchfactor = 0.0f; 359 SetStretchFactorLocked(laudio_stretchfactor); 233 360 } 361 else 362 { 363 SetStretchFactorLocked(audio_stretchfactor); 364 if (pSoundStretch) 365 { 366 // if its passthru then we need to reencode 367 if (audio_codec) 368 { 369 if (!encoder) 370 { 371 VERBOSE(VB_AUDIO, LOC + 372 QString("Creating Encoder for codec %1") 373 .arg(audio_codec->codec_id)); 234 374 375 encoder = new AudioOutputDigitalEncoder(); 376 if (!encoder->Init(audio_codec->codec_id, 377 audio_codec->bit_rate, 378 audio_codec->sample_rate, 379 audio_codec->channels 380 )) 381 { 382 // eeks 383 delete encoder; 384 encoder = NULL; 385 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 386 } 387 } 388 } 389 if (encoder) 390 { 391 pSoundStretch->setSampleRate(audio_codec->sample_rate); 392 pSoundStretch->setChannels(audio_codec->channels); 393 } 394 else 395 { 396 pSoundStretch->setSampleRate(audio_samplerate); 397 pSoundStretch->setChannels(audio_channels); 398 } 399 } 400 } 401 235 402 // Setup visualisations, zero the visualisations buffers 236 403 prepareVisuals(); 237 404 … … 290 457 pSoundStretch = NULL; 291 458 } 292 459 460 if (encoder) 461 { 462 delete encoder; 463 encoder = NULL; 464 } 465 466 if (upmixer) 467 { 468 delete upmixer; 469 upmixer = NULL; 470 } 471 needs_upmix = false; 472 293 473 CloseDevice(); 294 474 295 475 killAudioLock.unlock(); … … 303 483 304 484 void AudioOutputBase::Pause(bool paused) 305 485 { 486 VERBOSE(VB_AUDIO, LOC + QString("Pause %0").arg(paused)); 306 487 pauseaudio = paused; 307 488 audio_actually_paused = false; 308 489 } … … 385 566 The reason is that computing 'audiotime' requires acquiring the audio 386 567 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 568 from the audio thread, and then call this from the video thread. */ 388 intret;569 long long ret; 389 570 struct timeval now; 390 571 391 572 if (audiotime == 0) … … 397 578 398 579 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 580 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);581 ret = (long long)(ret * audio_stretchfactor); 401 582 583 #if 1 584 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 585 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 586 .arg(now.tv_sec).arg(now.tv_usec) 587 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 588 .arg(ret) 589 .arg(audiotime) 590 .arg(audio_stretchfactor) 591 ); 592 #endif 593 402 594 ret += audiotime; 403 595 404 596 pthread_mutex_unlock(&avsync_lock); 405 return ret;597 return (int)ret; 406 598 } 407 599 408 600 void AudioOutputBase::SetAudiotime(void) … … 439 631 // include algorithmic latencies 440 632 if (pSoundStretch) 441 633 { 634 // add the effect of any unused but processed samples, 635 // AC3 reencode does this 636 totalbuffer += (int)(pSoundStretch->numSamples() * 637 audio_bytes_per_sample); 442 638 // add the effect of unprocessed samples in time stretch algo 443 639 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 640 audio_bytes_per_sample) / audio_stretchfactor); 445 641 } 446 642 643 if (upmixer && needs_upmix) 644 { 645 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 646 } 647 447 648 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 649 (audio_bytes_per_sample * effdspstretched)); 449 650 450 651 gettimeofday(&audiotime_updated, NULL); 652 #if 1 653 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 654 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 655 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 656 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 657 .arg(audiotime) 658 .arg(audbuf_timecode) 659 .arg(totalbuffer) 660 .arg(soundcard_buffer) 661 .arg(effdspstretched) 662 .arg(audio_bytes_per_sample) 663 .arg(audio_stretchfactor) 664 ); 665 #endif 451 666 452 667 pthread_mutex_unlock(&avsync_lock); 453 668 pthread_mutex_unlock(&audio_buflock); … … 458 673 { 459 674 // NOTE: This function is not threadsafe 460 675 int afree = audiofree(true); 461 int abps = audio_bytes_per_sample; 676 int abps = (encoder) ? 677 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 462 678 int len = samples * abps; 463 679 464 680 // Check we have enough space to write the data 465 681 if (need_resampler && src_ctx) 466 682 len = (int)ceilf(float(len) * src_data.src_ratio); 467 683 684 // include samples in upmix buffer that may be flushed 685 if (needs_upmix && upmixer) 686 len += upmixer->numUnprocessedSamples() * abps; 687 468 688 if (pSoundStretch) 469 689 len += (pSoundStretch->numUnprocessedSamples() + 470 690 (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps; … … 520 740 // NOTE: This function is not threadsafe 521 741 522 742 int afree = audiofree(true); 523 int abps = audio_bytes_per_sample; 743 int abps = (encoder) ? 744 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 524 745 int len = samples * abps; 525 746 526 747 // Check we have enough space to write the data 527 748 if (need_resampler && src_ctx) 528 749 len = (int)ceilf(float(len) * src_data.src_ratio); 529 750 751 // include samples in upmix buffer that may be flushed 752 if (needs_upmix && upmixer) 753 len += upmixer->numUnprocessedSamples() * abps; 754 530 755 if (pSoundStretch) 531 756 { 532 757 len += (pSoundStretch->numUnprocessedSamples() + … … 575 800 576 801 int AudioOutputBase::WaitForFreeSpace(int samples) 577 802 { 578 int len = samples * audio_bytes_per_sample; 803 int abps = (encoder) ? 804 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 805 int len = samples * abps; 579 806 int afree = audiofree(false); 580 807 581 808 while (len > afree) 582 809 { 583 810 if (blocking) 584 811 { 585 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +812 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 586 813 QString("(need %1, available %2)").arg(len).arg(afree)); 587 814 588 815 // wait for more space … … 591 818 } 592 819 else 593 820 { 594 VERBOSE(VB_IMPORTANT, LOC_ERR + 595 "Audio buffer overflow, audio data lost!"); 596 samples = afree / audio_bytes_per_sample; 597 len = samples * audio_bytes_per_sample; 821 VERBOSE(VB_IMPORTANT, LOC_ERR + 822 QString("Audio buffer overflow, %1 audio samples lost!") 823 .arg(samples - (afree / abps))); 824 samples = afree / abps; 825 len = samples * abps; 598 826 if (src_ctx) 599 827 { 600 828 int error = src_reset(src_ctx); … … 619 847 620 848 int afree = audiofree(false); 621 849 622 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 623 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 624 .arg(samples * audio_bytes_per_sample) 625 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 850 int abps = (encoder) ? 851 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 852 853 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 854 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, " 855 "free=%4, timecode=%5 needsupmix %6") 856 .arg(samples) 857 .arg(samples * abps) 858 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 859 .arg(needs_upmix)); 626 860 627 len = WaitForFreeSpace(samples); 628 629 if (interleaved) 861 if (upmixer && needs_upmix) 630 862 { 631 char *mybuf = (char*)buffer; 632 int bdiff = AUDBUFSIZE - org_waud; 633 if (bdiff < len) 863 int out_samples = 0; 864 int step = (interleaved)?source_audio_channels:1; 865 len = WaitForFreeSpace(samples); // test 866 for (int itemp = 0; itemp < samples; ) 634 867 { 635 memcpy(audiobuffer + org_waud, mybuf, bdiff); 636 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 868 // just in case it does a processing cycle, release the lock 869 // to allow the output loop to do output 870 pthread_mutex_unlock(&audio_buflock); 871 if (audio_bytes == 2) 872 { 873 itemp += upmixer->putSamples( 874 (short*)buffer + itemp * step, 875 samples - itemp, 876 source_audio_channels, 877 (interleaved) ? 0 : samples); 878 } 879 else 880 { 881 itemp += upmixer->putSamples( 882 (char*)buffer + itemp * step, 883 samples - itemp, 884 source_audio_channels, 885 (interleaved) ? 0 : samples); 886 } 887 pthread_mutex_lock(&audio_buflock); 888 889 int copy_samples = upmixer->numSamples(); 890 if (copy_samples) 891 { 892 int copy_len = copy_samples * abps; 893 out_samples += copy_samples; 894 if (out_samples > samples) 895 len = WaitForFreeSpace(out_samples); 896 int bdiff = AUDBUFSIZE - org_waud; 897 if (bdiff < copy_len) 898 { 899 int bdiff_samples = bdiff/abps; 900 upmixer->receiveSamples( 901 (short*)(audiobuffer + org_waud), bdiff_samples); 902 upmixer->receiveSamples( 903 (short*)(audiobuffer), (copy_samples - bdiff_samples)); 904 } 905 else 906 { 907 upmixer->receiveSamples( 908 (short*)(audiobuffer + org_waud), copy_samples); 909 } 910 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 911 } 637 912 } 638 else 639 memcpy(audiobuffer + org_waud, mybuf, len); 640 641 org_waud = (org_waud + len) % AUDBUFSIZE; 642 } 643 else 913 914 if (samples > 0) 915 len = WaitForFreeSpace(out_samples); 916 917 samples = out_samples; 918 } 919 else 644 920 { 645 char **mybuf = (char**)buffer; 646 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 921 len = WaitForFreeSpace(samples); 922 923 if (interleaved) 647 924 { 648 for (int chan = 0; chan < audio_channels; chan++) 925 char *mybuf = (char*)buffer; 926 int bdiff = AUDBUFSIZE - org_waud; 927 if (bdiff < len) 649 928 { 650 audiobuffer[org_waud++] = mybuf[chan][itemp]; 651 if (audio_bits == 16) 652 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 929 memcpy(audiobuffer + org_waud, mybuf, bdiff); 930 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 931 } 932 else 933 { 934 memcpy(audiobuffer + org_waud, mybuf, len); 935 } 936 937 org_waud = (org_waud + len) % AUDBUFSIZE; 938 } 939 else 940 { 941 char **mybuf = (char**)buffer; 942 for (int itemp = 0; itemp < samples * audio_bytes; 943 itemp += audio_bytes) 944 { 945 for (int chan = 0; chan < audio_channels; chan++) 946 { 947 audiobuffer[org_waud++] = mybuf[chan][itemp]; 948 if (audio_bits == 16) 949 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 653 950 654 if (org_waud >= AUDBUFSIZE) 655 org_waud -= AUDBUFSIZE; 951 if (org_waud >= AUDBUFSIZE) 952 org_waud -= AUDBUFSIZE; 953 } 656 954 } 657 955 } 658 956 } 659 957 660 if ( pSoundStretch)958 if (samples > 0) 661 959 { 662 // does not change the timecode, only the number of samples 663 // back to orig pos 664 org_waud = waud; 665 int bdiff = AUDBUFSIZE - org_waud; 666 int nSamplesToEnd = bdiff/audio_bytes_per_sample; 667 if (bdiff < len) 960 if (pSoundStretch) 668 961 { 669 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +670 org_waud), nSamplesToEnd);671 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,672 (len - bdiff) / audio_bytes_per_sample);673 }674 else675 {676 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +677 org_waud), len / audio_bytes_per_sample);678 }679 962 680 int newLen = 0; 681 int nSamples; 682 len = WaitForFreeSpace(pSoundStretch->numSamples() * 683 audio_bytes_per_sample); 684 do 685 { 686 int samplesToGet = len/audio_bytes_per_sample; 687 if (samplesToGet > nSamplesToEnd) 963 // does not change the timecode, only the number of samples 964 // back to orig pos 965 org_waud = waud; 966 int bdiff = AUDBUFSIZE - org_waud; 967 int nSamplesToEnd = bdiff/abps; 968 if (bdiff < len) 688 969 { 689 samplesToGet = nSamplesToEnd; 970 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 971 (audiobuffer + 972 org_waud), nSamplesToEnd); 973 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 974 (len - bdiff) / abps); 690 975 } 976 else 977 { 978 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 979 (audiobuffer + org_waud), 980 len / abps); 981 } 691 982 692 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 693 (audiobuffer + org_waud), samplesToGet); 694 if (nSamples == nSamplesToEnd) 983 if (encoder) 695 984 { 696 org_waud = 0; 697 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 985 // pull out a packet's worth and reencode it until we 986 // don't have enough for any more packets 987 soundtouch::SAMPLETYPE *temp_buff = 988 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 989 size_t frameSize = encoder->FrameSize()/abps; 990 991 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 992 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 993 .arg(frameSize) 994 .arg(encoder->FrameSize()) 995 .arg(pSoundStretch->numSamples())); 996 997 // process the same number of samples as it creates 998 // a full encoded buffer just like before 999 while (pSoundStretch->numSamples() >= frameSize) 1000 { 1001 int got = pSoundStretch->receiveSamples( 1002 temp_buff, frameSize); 1003 int amount = encoder->Encode(temp_buff); 1004 1005 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1006 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1007 .arg(amount) 1008 .arg(got) 1009 .arg(pSoundStretch->numSamples())); 1010 1011 if (!amount) 1012 continue; 1013 1014 //len = WaitForFreeSpace(amount); 1015 char *ob = encoder->GetOutBuff(); 1016 if (amount >= bdiff) 1017 { 1018 memcpy(audiobuffer + org_waud, ob, bdiff); 1019 ob += bdiff; 1020 amount -= bdiff; 1021 org_waud = 0; 1022 } 1023 if (amount > 0) 1024 memcpy(audiobuffer + org_waud, ob, amount); 1025 1026 bdiff = AUDBUFSIZE - amount; 1027 org_waud += amount; 1028 } 698 1029 } 699 1030 else 700 1031 { 701 org_waud += nSamples * audio_bytes_per_sample; 702 nSamplesToEnd -= nSamples; 1032 int newLen = 0; 1033 int nSamples; 1034 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1035 audio_bytes_per_sample); 1036 do 1037 { 1038 int samplesToGet = len/audio_bytes_per_sample; 1039 if (samplesToGet > nSamplesToEnd) 1040 { 1041 samplesToGet = nSamplesToEnd; 1042 } 1043 1044 nSamples = pSoundStretch->receiveSamples( 1045 (soundtouch::SAMPLETYPE*) 1046 (audiobuffer + org_waud), samplesToGet); 1047 if (nSamples == nSamplesToEnd) 1048 { 1049 org_waud = 0; 1050 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1051 } 1052 else 1053 { 1054 org_waud += nSamples * audio_bytes_per_sample; 1055 nSamplesToEnd -= nSamples; 1056 } 1057 1058 newLen += nSamples * audio_bytes_per_sample; 1059 len -= nSamples * audio_bytes_per_sample; 1060 } while (nSamples > 0); 703 1061 } 1062 } 704 1063 705 newLen += nSamples * audio_bytes_per_sample; 706 len -= nSamples * audio_bytes_per_sample; 707 } while (nSamples > 0); 708 } 1064 waud = org_waud; 1065 lastaudiolen = audiolen(false); 709 1066 710 waud = org_waud; 711 lastaudiolen = audiolen(false); 1067 if (timecode < 0) 1068 { 1069 // mythmusic doesn't give timestamps.. 1070 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1071 } 1072 1073 samples_buffered += samples; 1074 1075 /* we want the time at the end -- but the file format stores 1076 time at the start of the chunk. */ 1077 // even with timestretch, timecode is still calculated from original 1078 // sample count 1079 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 712 1080 713 samples_buffered += samples; 714 715 if (timecode < 0) 716 { 717 // mythmusic doesn't give timestamps.. 718 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1081 if (interleaved) 1082 { 1083 dispatchVisual((unsigned char *)buffer, len, timecode, 1084 source_audio_channels, audio_bits); 1085 } 719 1086 } 720 721 /* we want the time at the end -- but the file format stores722 time at the start of the chunk. */723 // even with timestretch, timecode is still calculated from original724 // sample count725 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);726 1087 727 if (interleaved)728 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);729 730 1088 pthread_mutex_unlock(&audio_buflock); 731 1089 } 732 1090 … … 739 1097 740 1098 if (source_bitrate == -1) 741 1099 { 742 source_bitrate = audio_samplerate * audio_channels * audio_bits;1100 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 743 1101 } 744 1102 745 1103 if (ct / 1000 != current_seconds) … … 747 1105 current_seconds = ct / 1000; 748 1106 OutputEvent e(current_seconds, ct, 749 1107 source_bitrate, audio_samplerate, audio_bits, 750 audio_channels);1108 source_audio_channels); 751 1109 dispatch(e); 752 1110 } 753 1111 } … … 785 1143 786 1144 space_on_soundcard = getSpaceOnSoundcard(); 787 1145 788 if (space_on_soundcard != last_space_on_soundcard) { 789 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard") 1146 if (space_on_soundcard != last_space_on_soundcard) 1147 { 1148 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1149 LOC + QString("%1 bytes free on soundcard") 790 1150 .arg(space_on_soundcard)); 1151 791 1152 last_space_on_soundcard = space_on_soundcard; 792 1153 } 793 1154 … … 799 1160 WriteAudio(zeros, fragment_size); 800 1161 } else { 801 1162 // this should never happen now -dag 802 VERBOSE(VB_AUDIO , LOC +1163 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 803 1164 QString("waiting for space on soundcard " 804 1165 "to write zeros: have %1 need %2") 805 1166 .arg(space_on_soundcard).arg(fragment_size)); … … 835 1196 if (fragment_size > audiolen(true)) 836 1197 { 837 1198 if (audiolen(true) > 0) // only log if we're sending some audio 838 VERBOSE(VB_AUDIO , LOC +1199 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 839 1200 QString("audio waiting for buffer to fill: " 840 1201 "have %1 want %2") 841 1202 .arg(audiolen(true)).arg(fragment_size)); 842 1203 843 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail"); 1204 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1205 //LOC + "Broadcasting free space avail"); 844 1206 pthread_mutex_lock(&audio_buflock); 845 1207 pthread_cond_broadcast(&audio_bufsig); 846 1208 pthread_mutex_unlock(&audio_buflock); … … 854 1216 if (fragment_size > space_on_soundcard) 855 1217 { 856 1218 if (space_on_soundcard != last_space_on_soundcard) { 857 VERBOSE(VB_AUDIO , LOC +1219 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 858 1220 QString("audio waiting for space on soundcard: " 859 1221 "have %1 need %2") 860 1222 .arg(space_on_soundcard).arg(fragment_size)); … … 916 1278 917 1279 /* update raud */ 918 1280 raud = (raud + fragment_size) % AUDBUFSIZE; 919 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1281 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 920 1282 pthread_cond_broadcast(&audio_bufsig); 921 1283 922 1284 written_size = fragment_size; -
libs/libmyth/libmyth.pro
11 11 12 12 # Input 13 13 HEADERS += audiooutput.h audiooutputbase.h audiooutputnull.h 14 HEADERS += audiooutputdigitalencoder.h 14 15 HEADERS += backendselect.h dbsettings.h dialogbox.h 15 16 HEADERS += DisplayRes.h DisplayResScreen.h exitcodes.h 16 17 HEADERS += generictree.h httpcomms.h langsettings.h lcddevice.h … … 25 26 HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h 26 27 HEADERS += mythhdd.h mythcdrom.h 27 28 HEADERS += compat.h 29 HEADERS += audiooutputdigitalencoder.h 28 30 29 31 SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp 32 SOURCES += audiooutputdigitalencoder.cpp 30 33 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp 31 34 SOURCES += DisplayRes.cpp DisplayResScreen.cpp 32 35 SOURCES += generictree.cpp httpcomms.cpp langsettings.cpp lcddevice.cpp … … 41 44 SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp 42 45 SOURCES += mythhdd.cpp mythcdrom.cpp 43 46 44 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./ 47 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../libmythfreesurround 48 INCLUDEPATH += ../libavcodec ../libavutil 49 INCLUDEPATH += ../.. ../ ./ 45 50 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 46 DEPENDPATH += ../libmythupnp 51 DEPENDPATH += ../libmythupnp ../libmythfreesurround ../libavcodec ../libavutil 47 52 48 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}49 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}50 LIBS += -L../libmythui -lmythui-$${LIBVERSION}51 LIBS += -L../libmythupnp -lmythupnp-$${LIBVERSION}52 53 54 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 55 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 56 LIBS += -L../libmythui -lmythui-$${LIBVERSION} 57 LIBS += -L../libmythupnp -lmythupnp-$${LIBVERSION} 58 LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION} 59 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 60 LIBS += -L../libavutil -lmythavutil-$${LIBVERSION} 61 LIBS += -lfftw3f 62 53 63 TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT} 54 64 TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT} 65 TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT} 55 66 56 67 # Install headers so that plugins can compile independently 57 68 inc.path = $${PREFIX}/include/mythtv/ … … 221 232 use_hidesyms { 222 233 QMAKE_CXXFLAGS += -fvisibility=hidden 223 234 } 235 236 contains( CONFIG_LIBA52, yes ) { 237 LIBS += -la52 238 } -
libs/libmyth/audiooutputdx.cpp
130 130 // FIXME: kedl: not sure what else could be required here? 131 131 } 132 132 133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 134 int audio_samplerate, int audio_passthru) 133 void AudioOutputDX::Reconfigure(int audio_bits, 134 int audio_channels, 135 int audio_samplerate, 136 int audio_passthru, 137 AudioCodecMode laom) 135 138 { 136 139 if (dsbuffer) 137 140 DestroyDSBuffer(); -
libs/libmyth/audiooutput.h
31 31 virtual ~AudioOutput() { }; 32 32 33 33 // reconfigure sound out for new params 34 virtual void Reconfigure(int audio_bits, int audio_channels, 35 int audio_samplerate, bool audio_passthru) = 0; 34 virtual void Reconfigure(int audio_bits, 35 int audio_channels, 36 int audio_samplerate, 37 bool audio_passthru, 38 void* audio_codec = NULL) = 0; 36 39 37 40 virtual void SetStretchFactor(float factor); 41 virtual float GetStretchFactor(void) { return 1.0f; } 38 42 39 43 // do AddSamples calls block? 40 44 virtual void SetBlocking(bool blocking) = 0; … … 76 80 lastError = msg; 77 81 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 78 82 } 83 void ClearError(void) { lastError = QString::null; } 79 84 80 85 void Warn(QString msg) 81 86 { -
libs/libmyth/audiooutputdx.h
35 35 /// END HACK HACK HACK HACK 36 36 37 37 virtual void Reset(void); 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, int audio_passthru); 38 virtual void Reconfigure(int audio_bits, 39 int audio_channels, 40 int audio_samplerate, 41 bool audio_passthru, 42 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 40 43 virtual void SetBlocking(bool blocking); 41 44 42 45 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
programs/mythfrontend/globalsettings.cpp
56 56 } 57 57 #endif 58 58 #ifdef USING_ALSA 59 gc->addSelection("ALSA:default", "ALSA:default"); 59 gc->addSelection("ALSA:default", "ALSA:default"); 60 gc->addSelection("ALSA:surround51", "ALSA:surround51"); 61 gc->addSelection("ALSA:analog", "ALSA:analog"); 62 gc->addSelection("ALSA:digital", "ALSA:digital"); 63 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 64 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 60 65 #endif 61 66 #ifdef USING_ARTS 62 67 gc->addSelection("ARTS:", "ARTS:"); … … 78 83 return gc; 79 84 } 80 85 86 static HostComboBox *MaxAudioChannels() 87 { 88 HostComboBox *gc = new HostComboBox("MaxChannels",false); 89 gc->setLabel(QObject::tr("Max Audio Channels")); 90 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 91 gc->addSelection(QObject::tr("5.1"), "6"); 92 gc->setHelpText( 93 QObject::tr( 94 "Set the maximum number of audio channels to be decoded. " 95 "This is for multi-channel/surround audio playback.")); 96 return gc; 97 } 98 99 static HostComboBox *AudioUpmixType() 100 { 101 HostComboBox *gc = new HostComboBox("AudioUpmixType",false); 102 gc->setLabel(QObject::tr("Upmix")); 103 gc->addSelection(QObject::tr("Passive"), "0"); 104 gc->addSelection(QObject::tr("Active Simple"), "1"); 105 gc->addSelection(QObject::tr("Active Linear"), "2", true); // default 106 gc->setHelpText( 107 QObject::tr( 108 "Set the audio upmix type for 2ch to 6ch conversion. " 109 "This is for multi-channel/surround audio playback.")); 110 return gc; 111 } 112 81 113 static HostComboBox *PassThroughOutputDevice() 82 114 { 83 115 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3156 3188 vgrp0->addChild(AC3PassThrough()); 3157 3189 vgrp0->addChild(DTSPassThrough()); 3158 3190 3191 HorizontalConfigurationGroup *agrp = 3192 new HorizontalConfigurationGroup(false, false, true, true); 3193 agrp->addChild(MaxAudioChannels()); 3194 agrp->addChild(AudioUpmixType()); 3195 addChild(agrp); 3196 3159 3197 VerticalConfigurationGroup *vgrp1 = 3160 3198 new VerticalConfigurationGroup(false, false, true, true); 3161 3199 vgrp1->addChild(AggressiveBuffer()); -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 virtual void Reconfigure(int audio_bits, int audio_channels, 58 int audio_samplerate, bool audio_passthru) 58 int audio_samplerate, bool audio_passthru, 59 void *audio_codec = NULL) 59 60 { 61 ClearError(); 60 62 (void)audio_samplerate; 61 63 (void)audio_passthru; 64 (void)audio_codec; 62 65 bits = audio_bits; 63 66 channels = audio_channels; 64 67 bytes_per_sample = bits * channels / 8; 68 if ((uint)audio_channels > 2) 69 Error(QString("Invalid channel count %1").arg(channels)); 65 70 } 66 71 67 72 // dsprate is in 100 * samples/second