Ticket #6975: new_audio-22186.diff
File new_audio-22186.diff, 98.0 KB (added by , 16 years ago) |
---|
-
mythplugins/mythmusic/mythmusic/playbackbox.cpp
365 365 changeSpeed(true); 366 366 else if (action == "MUTE") 367 367 toggleMute(); 368 else if (action == "TOGGLEUPMIX") 369 toggleUpmix(); 368 370 else if (action == "MENU" && visualizer_status != 2) 369 371 { 370 372 menufilters = false; … … 1202 1204 } 1203 1205 } 1204 1206 1207 void PlaybackBoxMusic::toggleUpmix() 1208 { 1209 if (gPlayer->getOutput()) 1210 gPlayer->getOutput()->ToggleUpmix(); 1211 } 1212 1213 1205 1214 void PlaybackBoxMusic::showProgressBar() 1206 1215 { 1207 1216 if (progress_bar && visualizer_status != 2) -
mythplugins/mythmusic/mythmusic/globalsettings.cpp
67 67 return gc; 68 68 }; 69 69 70 static HostCheckBox *MusicUpmixer() 71 { 72 HostCheckBox *gc = new HostCheckBox("MusicDefaultUpmix"); 73 gc->setLabel(QObject::tr("Upconvert stereo to 5.1 surround")); 74 gc->setValue(false); 75 gc->setHelpText(QObject::tr("MythTV can upconvert stereo tracks to 5.1 audio. " 76 "Set this option to enable it by default. " 77 "You can enable or disable the upconversion during playback at anytime.")); 78 return gc; 79 }; 80 70 81 static HostLineEdit *CDDevice() 71 82 { 72 83 HostLineEdit *gc = new HostLineEdit("CDDevice"); … … 545 556 general->setLabel(QObject::tr("General Settings (1)")); 546 557 general->addChild(SetMusicDirectory()); 547 558 general->addChild(MusicAudioDevice()); 559 general->addChild(MusicUpmixer()); 548 560 general->addChild(CDDevice()); 549 561 general->addChild(AutoLookupCD()); 550 562 general->addChild(AutoPlayCD()); -
mythplugins/mythmusic/mythmusic/avfdecoder.cpp
256 256 if (output()) 257 257 { 258 258 const AudioSettings settings( 259 16 /*bits*/, m_audioDec->channels, m_audioDec-> sample_rate,260 false /* AC3/DTS pass through */);259 16 /*bits*/, m_audioDec->channels, m_audioDec->codec_id, 260 m_audioDec->sample_rate, false /* AC3/DTS pass through */); 261 261 output()->Reconfigure(settings); 262 262 output()->SetSourceBitrate(m_audioDec->bit_rate); 263 263 } -
mythplugins/mythmusic/mythmusic/main.cpp
389 389 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 390 390 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 391 391 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 392 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 392 393 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 393 394 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 394 395 REG_KEY("Music", "THMBUP", "Increase rating", "9"); -
mythplugins/mythmusic/mythmusic/musicplayer.cpp
348 348 349 349 void MusicPlayer::openOutputDevice(void) 350 350 { 351 QString adevice ;351 QString adevice, pdevice; 352 352 353 353 if (gContext->GetSetting("MusicAudioDevice") == "default") 354 354 adevice = gContext->GetSetting("AudioOutputDevice"); 355 355 else 356 356 adevice = gContext->GetSetting("MusicAudioDevice"); 357 357 358 pdevice = gContext->GetSetting("PassThruOutputDevice"); 359 358 360 // TODO: Error checking that device is opened correctly! 359 m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100, 360 AUDIOOUTPUT_MUSIC, true, false); 361 m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 0, 44100, 362 AUDIOOUTPUT_MUSIC, true, false, 363 gContext->GetNumSetting("MusicDefaultUpmix", 0) + 1); 361 364 m_output->setBufferSize(256 * 1024); 362 365 m_output->SetBlocking(false); 363 366 -
mythplugins/mythmusic/mythmusic/playbackbox.h
69 69 void changeVolume(bool up_or_down); 70 70 void changeSpeed(bool up_or_down); 71 71 void toggleMute(); 72 void toggleUpmix(); 72 73 void resetTimer(); 73 74 void hideVolume(){showVolume(false);} 74 75 void showVolume(bool on_or_off); -
mythplugins/mythmusic/mythmusic/cddecoder.cpp
14 14 15 15 #include <mythtv/mythcontext.h> 16 16 #include <mythtv/mythmediamonitor.h> 17 #include <mythtv/libavcodec/avcodec.h> 17 18 18 19 CdDecoder::CdDecoder(const QString &file, DecoderFactory *d, QIODevice *i, 19 20 AudioOutput *o) : … … 149 150 if (output()) 150 151 { 151 152 const AudioSettings settings( 152 16 /*bits*/, chan, freq, false /* AC3/DTS passthru */); 153 16 /*bits*/, chan, CODEC_ID_PCM_S16LE, freq, 154 false /* AC3/DTS passthru */); 153 155 output()->Reconfigure(settings); 154 156 output()->SetSourceBitrate(44100 * 2 * 16); 155 157 } -
mythtv/libs/libmythtv/nuppeldecoder.cpp
496 496 #endif 497 497 GetNVP()->SetAudioParams(extradata.audio_bits_per_sample, 498 498 extradata.audio_channels, 499 CODEC_ID_NONE, 499 500 extradata.audio_sample_rate, 500 501 false /* AC3/DTS pass through */); 501 502 GetNVP()->ReinitAudio(); -
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
212 212 audioOutput(NULL), 213 213 audio_main_device(QString::null), 214 214 audio_passthru_device(QString::null), 215 audio_channels(2), audio_ bits(-1),216 audio_ samplerate(44100), audio_stretchfactor(1.0f),217 audio_ codec(NULL),audio_lock(QMutex::Recursive),215 audio_channels(2), audio_codec(0), 216 audio_bits(-1), audio_samplerate(44100), 217 audio_stretchfactor(1.0f), audio_lock(QMutex::Recursive), 218 218 audio_muted_on_creation(muted), 219 219 // Picture-in-Picture stuff 220 220 pip_active(false), pip_visible(true), … … 911 911 audioOutput = AudioOutput::OpenAudio(audio_main_device, 912 912 audio_passthru_device, 913 913 audio_bits, audio_channels, 914 audio_ samplerate,914 audio_codec, audio_samplerate, 915 915 AUDIOOUTPUT_VIDEO, 916 916 setVolume, audio_passthru); 917 917 if (!audioOutput) … … 944 944 945 945 if (audioOutput) 946 946 { 947 const AudioSettings settings( 948 audio_bits, audio_channels, audio_samplerate, 949 audio_passthru, audio_codec); 947 const AudioSettings settings(audio_bits, audio_channels, audio_codec, 948 audio_samplerate, audio_passthru); 950 949 audioOutput->Reconfigure(settings); 950 if (audio_passthru) 951 audio_channels = 2; 951 952 errMsg = audioOutput->GetError(); 952 953 if (!errMsg.isEmpty()) 953 954 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3916 3917 return !IsErrored(); 3917 3918 } 3918 3919 3919 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, 3920 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, int codec, 3920 3921 int samplerate, bool passthru) 3921 3922 { 3922 3923 audio_bits = bps; 3923 3924 audio_channels = channels; 3925 audio_codec = codec; 3924 3926 audio_samplerate = samplerate; 3925 3927 audio_passthru = passthru; 3926 3928 } 3927 3929 3928 void NuppelVideoPlayer::SetAudioCodec(void *ac)3929 {3930 audio_codec = ac;3931 }3932 3933 3930 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3934 3931 { 3935 3932 if (audioOutput) … … 5353 5350 } 5354 5351 } 5355 5352 5353 bool NuppelVideoPlayer::ToggleUpmix() 5354 { 5355 if (audioOutput) 5356 return audioOutput->ToggleUpmix(); 5357 return false; 5358 } 5359 5356 5360 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5357 5361 { 5358 5362 if (videoOutput) -
mythtv/libs/libmythtv/avformatdecoder.cpp
461 461 // Audio 462 462 audioSamples(NULL), 463 463 allow_ac3_passthru(false), allow_dts_passthru(false), 464 internal_vol(false), 464 465 disable_passthru(false), max_channels(2), 465 dummy_frame(NULL),466 last_ac3_channels(0), dummy_frame(NULL), 466 467 // DVD 467 468 lastdvdtitle(-1), 468 469 decodeStillFrame(false), … … 480 481 av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR); 481 482 av_log_set_callback(myth_av_log); 482 483 483 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);484 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);485 484 max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2); 485 allow_ac3_passthru = (max_channels > 2) ? gContext->GetNumSetting("AC3PassThru", false) : false; 486 allow_dts_passthru = (max_channels > 2) ? gContext->GetNumSetting("DTSPassThru", false) : false; 487 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 486 488 487 489 audioIn.sample_size = -32; // force SetupAudioStream to run once 488 490 itv = GetNVP()->GetInteractiveTV(); … … 2024 2026 // waiting on audio. 2025 2027 if (GetNVP()->HasAudioIn() && tracks[kTrackTypeAudio].empty()) 2026 2028 { 2027 GetNVP()->SetAudioParams(-1, -1, -1, false /* AC3/DTS pass-through */);2029 GetNVP()->SetAudioParams(-1, -1, CODEC_ID_NONE, -1, false /* AC3/DTS pass-through */); 2028 2030 GetNVP()->ReinitAudio(); 2029 2031 if (ringBuffer && ringBuffer->isDVD()) 2030 2032 audioIn = AudioInfo(); … … 3059 3061 { 3060 3062 int idx = atracks[i].av_stream_index; 3061 3063 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 3062 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&3063 !disable_passthru &&3064 (codec_ctx->codec_id == CODEC_ID_AC3));3065 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&3066 !disable_passthru &&3067 (codec_ctx->codec_id == CODEC_ID_DTS));3068 3064 AudioInfo item(codec_ctx->codec_id, 3069 3065 codec_ctx->sample_rate, codec_ctx->channels, 3070 do_ac3_passthru || do_dts_passthru);3066 DoPassThrough(codec_ctx)); 3071 3067 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 3072 3068 } 3073 3069 #endif … … 3201 3197 bool AvFormatDecoder::GetFrame(int onlyvideo) 3202 3198 { 3203 3199 AVPacket *pkt = NULL; 3200 AC3HeaderInfo hdr; 3204 3201 int len; 3205 3202 unsigned char *ptr; 3206 3203 int data_size = 0; … … 3638 3635 reselectAudioTrack = true; 3639 3636 } 3640 3637 3641 bool do_ac3_passthru =3642 (allow_ac3_passthru && !transcoding &&3643 (curstream->codec->codec_id == CODEC_ID_AC3));3644 bool do_dts_passthru =3645 (allow_dts_passthru && !transcoding &&3646 (curstream->codec->codec_id == CODEC_ID_DTS));3647 bool using_passthru = do_ac3_passthru || do_dts_passthru;3648 3649 3638 /// XXX HACK: set sample format to signed 16 bit 3650 3639 if (curstream->codec->codec_id == CODEC_ID_TRUEHD) 3651 3640 curstream->codec->sample_fmt = SAMPLE_FMT_S16; … … 3660 3649 QString("Setting channels to %1") 3661 3650 .arg(audioOut.channels)); 3662 3651 3663 if ( using_passthru)3652 if (DoPassThrough(curstream->codec)) 3664 3653 { 3665 3654 // for passthru let it select the max number 3666 3655 // of channels … … 3682 3671 reselectAudioTrack |= curstream->codec->channels; 3683 3672 } 3684 3673 3674 if (curstream->codec->codec_id == CODEC_ID_AC3) 3675 { 3676 GetBitContext gbc; 3677 init_get_bits(&gbc, ptr, len * 8); 3678 if (!ff_ac3_parse_header(&gbc, &hdr)) 3679 { 3680 if (hdr.channels != last_ac3_channels) 3681 { 3682 last_ac3_channels = curstream->codec->channels = hdr.channels; 3683 SetupAudioStream(); 3684 } 3685 } 3686 } 3687 3685 3688 if (reselectAudioTrack) 3686 3689 { 3687 3690 QMutexLocker locker(&avcodeclock); … … 4207 4210 } 4208 4211 } 4209 4212 4213 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 4214 { 4215 bool passthru = false; 4216 4217 if (ctx->codec_id == CODEC_ID_AC3) 4218 passthru = allow_ac3_passthru && 4219 ctx->channels >= (int)max_channels && 4220 !internal_vol; 4221 else if (ctx->codec_id == CODEC_ID_DTS) 4222 passthru = allow_dts_passthru && !internal_vol; 4223 4224 passthru &= !transcoding && !disable_passthru; 4225 // Don't know any cards that support spdif clocked at < 44100 4226 // Some US cable transmissions have 2ch 32k AC-3 streams 4227 passthru &= ctx->sample_rate >= 44100; 4228 4229 return passthru; 4230 } 4231 4210 4232 /** \fn AvFormatDecoder::SetupAudioStream(void) 4211 4233 * \brief Reinitializes audio if it needs to be reinitialized. 4212 4234 * … … 4220 4242 AVStream *curstream = NULL; 4221 4243 AVCodecContext *codec_ctx = NULL; 4222 4244 AudioInfo old_in = audioIn; 4223 AudioInfo old_out = audioOut;4224 4245 bool using_passthru = false; 4225 4246 4226 4247 if ((currentTrack[kTrackTypeAudio] >= 0) && … … 4234 4255 codec_ctx = curstream->codec; 4235 4256 if (codec_ctx) 4236 4257 { 4237 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4238 (codec_ctx->codec_id == CODEC_ID_AC3)); 4239 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4240 (codec_ctx->codec_id == CODEC_ID_DTS)); 4241 using_passthru = do_ac3_passthru || do_dts_passthru; 4242 info = AudioInfo(codec_ctx->codec_id, 4243 codec_ctx->sample_rate, codec_ctx->channels, 4244 using_passthru && !disable_passthru); 4258 using_passthru = DoPassThrough(codec_ctx); 4259 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4260 codec_ctx->channels, using_passthru); 4245 4261 } 4246 4262 } 4247 4263 … … 4258 4274 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4259 4275 4260 4276 audioOut = audioIn = info; 4261 AudioInfo tmpAudioOut = audioOut;4262 4277 4263 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4264 if (using_passthru && !disable_passthru) 4278 if (!using_passthru && audioOut.channels > (int)max_channels) 4265 4279 { 4266 tmpAudioOut.channels = 2; 4267 tmpAudioOut.sample_rate = 48000; 4268 tmpAudioOut.sample_size = 4; 4269 } 4270 4271 if (audioOut.channels > (int) max_channels) 4272 { 4273 audioOut.channels = (int) max_channels; 4280 audioOut.channels = (int)max_channels; 4274 4281 audioOut.sample_size = audioOut.channels * 2; 4275 codec_ctx->channels 4282 codec_ctx->channels = audioOut.channels; 4276 4283 } 4277 4284 4278 if (!using_passthru)4279 tmpAudioOut = audioOut;4280 4281 4285 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4282 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4283 .arg((using_passthru) ? "digital passthrough " : "") 4284 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4285 .arg(old_in.toString()).arg(old_out.toString()) 4286 .arg(audioIn.toString()).arg(audioOut.toString())); 4286 QString("\n\t\t\tfrom %1 to %2") 4287 .arg(old_in.toString()).arg(audioOut.toString())); 4287 4288 4288 if ( tmpAudioOut.sample_rate > 0)4289 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4289 if (audioOut.sample_rate > 0) 4290 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4290 4291 4291 GetNVP()->SetAudioParams(tmpAudioOut.bps(), tmpAudioOut.channels, 4292 tmpAudioOut.sample_rate, audioIn.do_passthru); 4292 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4293 audioOut.codec_id, audioOut.sample_rate, 4294 audioOut.do_passthru); 4293 4295 4294 // allow the audio stuff to reencode4295 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4296 4296 GetNVP()->ReinitAudio(); 4297 4297 4298 4298 return true; -
mythtv/libs/libmythtv/tv_play.h
430 430 bool TimeStretchHandleAction(PlayerContext*, 431 431 const QStringList &actions); 432 432 433 void ToggleUpmix(PlayerContext*); 433 434 void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true); 434 435 bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions); 435 436 -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
125 125 void SetAudioStretchFactor(float factor) { audio_stretchfactor = factor; } 126 126 void SetAudioOutput(AudioOutput *ao) { audioOutput = ao; } 127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru);128 void SetAudioParams(int bits, int channels, int codec, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 130 uint AdjustVolume(int change); 131 131 bool SetMuted(bool mute); … … 179 179 // Toggle Sets 180 180 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 181 181 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 182 bool ToggleUpmix(void); 182 183 183 184 // Gets 184 185 QSize GetVideoBufferSize(void) const { return video_dim; } … … 714 715 QString audio_main_device; 715 716 QString audio_passthru_device; 716 717 int audio_channels; 718 int audio_codec; 717 719 int audio_bits; 718 720 int audio_samplerate; 719 721 float audio_stretchfactor; 720 void *audio_codec;721 722 bool audio_passthru; 722 723 QMutex audio_lock; 723 724 bool audio_muted_on_creation; -
mythtv/libs/libmythtv/tv_play.cpp
496 496 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 497 497 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 498 498 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 499 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle audio upmixer", "Ctrl+U"); 499 500 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture view", 500 501 "V"); 501 502 REG_KEY("TV Playback", "TOGGLEPBPMODE", "Toggle Picture-by-Picture view", … … 633 634 Teletext F2,F3,F4,F5,F6,F7,F8 634 635 ITV F2,F3,F4,F5,F6,F7,F12 635 636 636 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 637 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 637 638 */ 638 639 } 639 640 … … 4354 4355 DoTogglePictureAttribute(ctx, kAdjustingPicture_Playback); 4355 4356 else if (has_action("TOGGLESTRETCH", actions)) 4356 4357 ToggleTimeStretch(ctx); 4358 else if (has_action("TOGGLEUPMIX", actions)) 4359 ToggleUpmix(ctx); 4357 4360 else if (has_action("TOGGLESLEEP", actions)) 4358 4361 ToggleSleepTimer(ctx); 4359 4362 else if (has_action("TOGGLERECORD", actions) && islivetv) … … 7987 7990 SetSpeedChangeTimer(0, __LINE__); 7988 7991 } 7989 7992 7993 void TV::ToggleUpmix(PlayerContext *ctx) 7994 { 7995 if (!ctx->nvp || !ctx->nvp->HasAudioOut()) 7996 return; 7997 QString text; 7998 if (ctx->nvp->ToggleUpmix()) 7999 text = tr("Upmixer On"); 8000 else 8001 text = tr("Upmixer Off"); 8002 8003 if (ctx->nvp->GetOSD() && !browsemode) 8004 ctx->nvp->GetOSD()->SetSettingsText(text, 5); 8005 } 8006 7990 8007 // dir in 10ms jumps 7991 8008 void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit) 7992 8009 { … … 9630 9647 SetManualZoom(actx, true, tr("Zoom Mode ON")); 9631 9648 else if (action == "TOGGLESTRETCH") 9632 9649 ToggleTimeStretch(actx); 9650 else if (action == "TOGGLEUPMIX") 9651 ToggleUpmix(actx); 9633 9652 else if (action.left(13) == "ADJUSTSTRETCH") 9634 9653 { 9635 9654 bool floatRead; … … 9995 10014 9996 10015 if (category == "AUDIOSYNC") 9997 10016 new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC"); 10017 else if (category == "TOGGLEUPMIX") 10018 new OSDGenericTree(treeMenu, tr("Toggle Audio Upmixer"), "TOGGLEUPMIX"); 9998 10019 else if (category == "TIMESTRETCH") 9999 10020 FillMenuTimeStretch(ctx, treeMenu); 10000 10021 else if (category == "VIDEOSCAN") -
mythtv/libs/libmythtv/tvosdmenuentry.cpp
232 232 curMenuEntries.append(new TVOSDMenuEntry( 233 233 "AUDIOSYNC", 1, 1, 1, 1, "Audio Sync")); 234 234 curMenuEntries.append(new TVOSDMenuEntry( 235 "TOGGLEUPMIX", 1, 1, 1, 1, "Toggle Upmixer")); 236 curMenuEntries.append(new TVOSDMenuEntry( 235 237 "TIMESTRETCH", 1, 1, 1, 1, "Time Stretch")); 236 238 curMenuEntries.append(new TVOSDMenuEntry( 237 239 "VIDEOSCAN", 1, 1, 1, 1, "Video Scan")); -
mythtv/libs/libmythtv/avformatdecoder.h
188 188 189 189 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 190 190 191 bool DoPassThrough(const AVCodecContext *ctx); 191 192 bool SetupAudioStream(void); 192 193 void SetupAudioStreamSubIndexes(int streamIndex); 193 194 void RemoveAudioStreams(); … … 258 259 short int *audioSamples; 259 260 bool allow_ac3_passthru; 260 261 bool allow_dts_passthru; 262 bool internal_vol; 261 263 bool disable_passthru; 262 264 uint max_channels; 265 uint last_ac3_channels; 263 266 264 267 VideoFrame *dummy_frame; 265 268 -
mythtv/libs/libmyth/audiooutputjack.h
23 23 virtual void WriteAudio(unsigned char *aubuf, int size); 24 24 virtual int GetSpaceOnSoundcard(void) const; 25 25 virtual int GetBufferedOnSoundcard(void) const; 26 vector<int> GetSupportedRates(void); 26 27 27 28 private: 28 29 -
mythtv/libs/libmyth/audiosettings.cpp
7 7 8 8 #include "audiosettings.h" 9 9 10 // startup_upmixer 10 11 AudioSettings::AudioSettings() : 11 12 main_device(QString::null), 12 13 passthru_device(QString::null), 13 14 bits(-1), 14 15 channels(-1), 16 codec(0), 15 17 samplerate(-1), 16 18 set_initial_vol(false), 17 19 use_passthru(false), 18 codec(NULL),19 source(AUDIOOUTPUT_UNKNOWN)20 source(AUDIOOUTPUT_UNKNOWN), 21 upmixer(0) 20 22 { 21 23 } 22 24 … … 25 27 passthru_device(other.passthru_device), 26 28 bits(other.bits), 27 29 channels(other.channels), 30 codec(other.codec), 28 31 samplerate(other.samplerate), 29 32 set_initial_vol(other.set_initial_vol), 30 33 use_passthru(other.use_passthru), 31 codec(other.codec),32 source(other.source)34 source(other.source), 35 upmixer(other.upmixer) 33 36 { 34 37 } 35 38 … … 38 41 const QString &audio_passthru_device, 39 42 int audio_bits, 40 43 int audio_channels, 44 int audio_codec, 41 45 int audio_samplerate, 42 46 AudioOutputSource audio_source, 43 47 bool audio_set_initial_vol, 44 48 bool audio_use_passthru, 45 void *audio_codec) :49 int upmixer_startup) : 46 50 main_device(audio_main_device), 47 51 passthru_device(audio_passthru_device), 48 52 bits(audio_bits), 49 53 channels(audio_channels), 54 codec(audio_codec), 50 55 samplerate(audio_samplerate), 51 56 set_initial_vol(audio_set_initial_vol), 52 57 use_passthru(audio_use_passthru), 53 codec(audio_codec),54 source(audio_source)58 source(audio_source), 59 upmixer(upmixer_startup) 55 60 { 56 61 } 57 62 58 63 AudioSettings::AudioSettings( 59 64 int audio_bits, 60 65 int audio_channels, 66 int audio_codec, 61 67 int audio_samplerate, 62 68 bool audio_use_passthru, 63 void *audio_codec) :69 int upmixer_startup) : 64 70 main_device(QString::null), 65 71 passthru_device(QString::null), 66 72 bits(audio_bits), 67 73 channels(audio_channels), 74 codec(audio_codec), 68 75 samplerate(audio_samplerate), 69 76 set_initial_vol(false), 70 77 use_passthru(audio_use_passthru), 71 codec(audio_codec),72 source(AUDIOOUTPUT_UNKNOWN)78 source(AUDIOOUTPUT_UNKNOWN), 79 upmixer(upmixer_startup) 73 80 { 74 81 } 75 82 -
mythtv/libs/libmyth/audiooutputbase.h
43 43 44 44 virtual void SetStretchFactor(float factor); 45 45 virtual float GetStretchFactor(void) const; 46 virtual bool ToggleUpmix(void); 46 47 47 48 virtual void Reset(void); 48 49 50 void SetSWVolume(int new_volume, bool save); 51 int GetSWVolume(void); 52 49 53 // timecode is in milliseconds. 50 54 virtual bool AddSamples(char *buffer, int samples, long long timecode); 51 55 virtual bool AddSamples(char *buffers[], int samples, long long timecode); … … 85 89 virtual void WriteAudio(unsigned char *aubuf, int size) = 0; 86 90 virtual int GetSpaceOnSoundcard(void) const = 0; 87 91 virtual int GetBufferedOnSoundcard(void) const = 0; 92 virtual vector<int> GetSupportedRates(void) 93 { vector<int> rates; return rates; } 88 94 /// You need to call this from any implementation in the dtor. 89 95 void KillAudio(void); 90 96 … … 122 128 123 129 // Basic details about the audio stream 124 130 int audio_channels; 131 int audio_codec; 125 132 int audio_bytes_per_sample; 126 133 int audio_bits; 127 134 int audio_samplerate; … … 132 139 QString audio_passthru_device; 133 140 134 141 bool audio_passthru; 142 bool audio_enc; 143 bool audio_reenc; 135 144 136 145 float audio_stretchfactor; 137 AVCodecContext *audio_codec;138 146 AudioOutputSource source; 139 147 140 148 bool killaudio; … … 144 152 bool buffer_output_data_for_use; // used by AudioOutputNULL 145 153 146 154 int configured_audio_channels; 155 int orig_config_channels; 156 int src_quality; 147 157 148 158 private: 159 // software volume 160 template <class AudioDataType> 161 void _AdjustVolume(AudioDataType *buffer, int len, bool music); 162 void AdjustVolume(void *buffer, int len, bool music); 163 149 164 // resampler 150 165 bool need_resampler; 151 166 SRC_STATE *src_ctx; … … 160 175 void *_MonoToStereo(AudioDataType *s1, AudioDataType *s2, int samples); 161 176 162 177 int source_audio_channels; 178 int source_audio_samplerate; 163 179 int source_audio_bytes_per_sample; 164 180 bool needs_upmix; 165 181 int surround_mode; 182 bool allow_ac3_passthru; 183 float old_audio_stretchfactor; 184 int volume; 166 185 167 186 bool blocking; // do AddSamples calls block? 168 187 -
mythtv/libs/libmyth/audiooutputalsa.cpp
32 32 AudioOutputALSA::~AudioOutputALSA() 33 33 { 34 34 KillAudio(); 35 SetIECStatus(true); 35 36 } 36 37 38 void AudioOutputALSA::SetIECStatus(bool audio) 39 { 40 snd_ctl_t *ctl; 41 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 42 int spdif_index = -1; 43 snd_ctl_elem_list_t *clist; 44 snd_ctl_elem_id_t *cid; 45 snd_ctl_elem_value_t *cval; 46 snd_aes_iec958_t iec958; 47 int cidx, controls; 48 49 VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1") 50 .arg(audio ? "audio" : "non-audio")); 51 52 int err; 53 if ((err = snd_ctl_open(&ctl, "default", 0)) < 0) 54 { 55 Error(QString("AudioOutputALSA::SetIECStatus: snd_ctl_open(default): %1") 56 .arg(snd_strerror(err))); 57 return; 58 } 59 snd_ctl_elem_list_alloca(&clist); 60 snd_ctl_elem_list(ctl, clist); 61 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 62 snd_ctl_elem_list(ctl, clist); 63 controls = snd_ctl_elem_list_get_used(clist); 64 for (cidx = 0; cidx < controls; cidx++) 65 { 66 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 67 if (spdif_index < 0 || 68 snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index) 69 break; 70 } 71 72 if (cidx >= controls) 73 return; 74 75 snd_ctl_elem_id_alloca(&cid); 76 snd_ctl_elem_list_get_id(clist, cidx, cid); 77 snd_ctl_elem_value_alloca(&cval); 78 snd_ctl_elem_value_set_id(cval, cid); 79 snd_ctl_elem_read(ctl,cval); 80 snd_ctl_elem_value_get_iec958(cval, &iec958); 81 82 if (!audio) 83 iec958.status[0] |= IEC958_AES0_NONAUDIO; 84 else 85 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 86 87 snd_ctl_elem_value_set_iec958(cval, &iec958); 88 snd_ctl_elem_write(ctl, cval); 89 } 90 91 vector<int> AudioOutputALSA::GetSupportedRates() 92 { 93 snd_pcm_hw_params_t *params; 94 int err; 95 const int srates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000 }; 96 vector<int> rates(srates, srates + sizeof(srates) / sizeof(int) ); 97 QString real_device; 98 99 if (audio_passthru || audio_enc) 100 real_device = audio_passthru_device; 101 else 102 real_device = audio_main_device; 103 104 if((err = snd_pcm_open(&pcm_handle, real_device.toAscii(), 105 SND_PCM_STREAM_PLAYBACK, 106 SND_PCM_NONBLOCK|SND_PCM_NO_AUTO_RESAMPLE)) < 0) 107 { 108 Error(QString("snd_pcm_open(%1): %2") 109 .arg(real_device).arg(snd_strerror(err))); 110 111 if (pcm_handle) 112 { 113 snd_pcm_close(pcm_handle); 114 pcm_handle = NULL; 115 } 116 rates.clear(); 117 return rates; 118 } 119 120 snd_pcm_hw_params_alloca(¶ms); 121 122 if ((err = snd_pcm_hw_params_any(pcm_handle, params)) < 0) 123 { 124 Error(QString("Broken configuration for playback; no configurations" 125 " available: %1").arg(snd_strerror(err))); 126 snd_pcm_close(pcm_handle); 127 pcm_handle = NULL; 128 rates.clear(); 129 return rates; 130 } 131 132 vector<int>::iterator it = rates.begin(); 133 134 while (it != rates.end()) 135 { 136 if(snd_pcm_hw_params_test_rate(pcm_handle, params, *it, 0) < 0) 137 it = rates.erase(it); 138 else 139 it++; 140 } 141 142 snd_pcm_close(pcm_handle); 143 pcm_handle = NULL; 144 145 return rates; 146 } 147 37 148 bool AudioOutputALSA::OpenDevice() 38 149 { 39 150 snd_pcm_format_t format; 40 151 unsigned int buffer_time, period_time; 41 152 int err; 153 QString real_device; 42 154 43 155 if (pcm_handle != NULL) 44 156 CloseDevice(); … … 46 158 pcm_handle = NULL; 47 159 numbadioctls = 0; 48 160 49 QString real_device = (audio_passthru) ? 50 audio_passthru_device : audio_main_device; 161 if (audio_passthru || audio_enc) 162 { 163 real_device = audio_passthru_device; 164 SetIECStatus(false); 165 } 166 else 167 { 168 real_device = audio_main_device; 169 SetIECStatus(true); 170 } 51 171 52 172 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 173 .arg(real_device)); … … 662 782 if (mixer_handle != NULL) 663 783 CloseMixer(); 664 784 785 if (alsadevice.toLower() == "software") 786 return; 787 665 788 VERBOSE(VB_AUDIO, QString("Opening mixer %1").arg(device)); 666 789 667 790 // TODO: This is opening card 0. Fix for case of multiple soundcards -
mythtv/libs/libmyth/volumebase.cpp
10 10 internal_vol(false), volume(80), 11 11 current_mute_state(kMuteOff) 12 12 { 13 swvol = swvol_setting = 14 (gContext->GetSetting("MixerDevice", "default").toLower() == "software"); 13 15 } 14 16 17 bool VolumeBase::SWVolume(void) 18 { 19 return swvol; 20 } 21 22 void VolumeBase::SWVolume(bool set) 23 { 24 if (swvol_setting) 25 return; 26 swvol = set; 27 } 28 15 29 uint VolumeBase::GetCurrentVolume(void) const 16 30 { 17 31 return volume; … … 76 90 void VolumeBase::UpdateVolume(void) 77 91 { 78 92 int new_volume = volume; 93 bool save = true; 79 94 if (current_mute_state == kMuteAll) 80 95 { 81 96 new_volume = 0; 97 save = false; 82 98 } 99 100 if (swvol) 101 { 102 SetSWVolume(new_volume, save); 103 return; 104 } 83 105 84 106 // TODO: Avoid assumption that there are 2 channels! 85 107 for (int i = 0; i < 2; i++) … … 102 124 void VolumeBase::SyncVolume(void) 103 125 { 104 126 // Read the volume from the audio driver and setup our internal state to match 105 volume = GetVolumeChannel(0); 127 if (swvol) 128 volume = GetSWVolume(); 129 else 130 volume = GetVolumeChannel(0); 106 131 } 107 132 -
mythtv/libs/libmyth/audiooutputjack.cpp
30 30 Reconfigure(settings); 31 31 } 32 32 33 vector<int> AudioOutputJACK::GetSupportedRates() 34 { 35 const int srates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000 }; 36 vector<int> rates(srates, srates + sizeof(srates) / sizeof(int) ); 37 unsigned long jack_port_flags = 0; 38 unsigned int jack_port_name_count = 1; 39 const char *jack_port_name = audio_main_device.toAscii(); 40 int err = -1; 41 audioid = -1; 42 vector<int>::iterator it = rates.begin(); 43 44 while (it != rates.end()) 45 { 46 unsigned long lrate = (unsigned long) *it; 47 err = JACK_OpenEx(&audioid, 16, &lrate, 48 2, 2, &jack_port_name, jack_port_name_count, 49 jack_port_flags); 50 51 if (err == ERR_OPENING_JACK) 52 { 53 Error(QString("Error connecting to jackd: %1. Is it running?") 54 .arg(audio_main_device)); 55 rates.clear(); 56 return rates; 57 } 58 else 59 if (err == ERR_RATE_MISMATCH) 60 it = rates.erase(it); 61 else 62 it++; 63 64 JACK_Close(audioid); 65 audioid = -1; 66 } 67 return rates; 68 } 69 70 33 71 AudioOutputJACK::~AudioOutputJACK() 34 72 { 35 73 // Close down all audio stuff -
mythtv/libs/libmyth/audiooutputoss.h
23 23 virtual void WriteAudio(unsigned char *aubuf, int size); 24 24 virtual int GetSpaceOnSoundcard(void) const; 25 25 virtual int GetBufferedOnSoundcard(void) const; 26 vector<int> GetSupportedRates(void); 26 27 27 28 private: 28 29 void VolumeInit(void); -
mythtv/libs/libmyth/audiooutputbase.cpp
1 1 // Std C headers 2 2 #include <cmath> 3 #include <limits> 3 4 4 5 // POSIX headers 5 6 #include <unistd.h> … … 21 22 AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 22 23 // protected 23 24 effdsp(0), effdspstretched(0), 24 audio_channels(-1), audio_ bytes_per_sample(0),25 audio_b its(-1), audio_samplerate(-1),26 audio_ buffer_unused(0),25 audio_channels(-1), audio_codec(CODEC_ID_NONE), 26 audio_bytes_per_sample(0), audio_bits(-1), 27 audio_samplerate(-1), audio_buffer_unused(0), 27 28 fragment_size(0), soundcard_buffer_size(0), 28 29 29 30 audio_main_device(settings.GetMainDevice()), 30 31 audio_passthru_device(settings.GetPassthruDevice()), 31 audio_passthru(false), audio_stretchfactor(1.0f), 32 audio_passthru(false), audio_enc(false), 33 audio_reenc(false), audio_stretchfactor(1.0f), 32 34 33 audio_codec(NULL),34 35 source(settings.source), killaudio(false), 35 36 36 37 pauseaudio(false), audio_actually_paused(false), … … 48 49 encoder(NULL), 49 50 upmixer(NULL), 50 51 source_audio_channels(-1), 52 source_audio_samplerate(0), 51 53 source_audio_bytes_per_sample(0), 52 54 needs_upmix(false), 53 55 surround_mode(FreeSurround::SurroundModePassive), 56 old_audio_stretchfactor(1.0), 57 volume(80), 54 58 55 59 blocking(false), 56 60 … … 62 66 raud(0), waud(0), 63 67 audbuf_timecode(0), 64 68 65 numlowbuffer(0),killAudioLock(QMutex::NonRecursive),69 killAudioLock(QMutex::NonRecursive), 66 70 current_seconds(-1), source_bitrate(-1), 67 71 68 72 memory_corruption_test0(0xdeadbeef), … … 78 82 memset(tmp_buff, 0, sizeof(short) * kAudioTempBufSize); 79 83 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 80 84 memset(audiobuffer, 0, sizeof(char) * kAudioRingBufferSize); 81 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 85 orig_config_channels = gContext->GetNumSetting("MaxChannels", 2); 86 src_quality = gContext->GetNumSetting("AudioUpmixType", 2); 87 if (!settings.upmixer) 88 configured_audio_channels = gContext->GetNumSetting("AudioDefaultUpmix", false) ? orig_config_channels : 2; 89 else 90 if (settings.upmixer == 1) 91 configured_audio_channels = 2; 92 else 93 configured_audio_channels = 6; 82 94 95 allow_ac3_passthru = (orig_config_channels > 2) ? gContext->GetNumSetting("AC3PassThru", false) : false; 96 83 97 // You need to call Reconfigure from your concrete class. 84 98 // Reconfigure(laudio_bits, laudio_channels, 85 99 // laudio_samplerate, laudio_passthru); … … 124 138 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 139 .arg(audio_stretchfactor)); 126 140 pSoundStretch = new soundtouch::SoundTouch(); 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)); 141 pSoundStretch->setSampleRate(audio_samplerate); 142 pSoundStretch->setChannels(upmixer ? 143 configured_audio_channels : source_audio_channels); 135 144 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->channels141 ))142 {143 // eeks144 delete encoder;145 encoder = NULL;146 VERBOSE(VB_AUDIO, LOC +147 QString("Failed to Create Encoder"));148 }149 }150 }151 if (audio_codec && encoder)152 {153 pSoundStretch->setSampleRate(audio_codec->sample_rate);154 pSoundStretch->setChannels(audio_codec->channels);155 }156 else157 {158 pSoundStretch->setSampleRate(audio_samplerate);159 pSoundStretch->setChannels(audio_channels);160 }161 162 145 pSoundStretch->setTempo(audio_stretchfactor); 163 146 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 164 147 165 148 // don't need these with only tempo change 166 149 //pSoundStretch->setPitch(1.0); 167 150 //pSoundStretch->setRate(1.0); 168 169 151 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 152 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 153 } … … 183 165 return audio_stretchfactor; 184 166 } 185 167 168 bool AudioOutputBase::ToggleUpmix(void) 169 { 170 if (orig_config_channels == 2 || source_audio_channels > 2 || 171 audio_passthru) 172 return false; 173 if (configured_audio_channels == 6) 174 configured_audio_channels = 2; 175 else 176 configured_audio_channels = 6; 177 178 const AudioSettings settings(audio_bits, source_audio_channels, 179 audio_codec, source_audio_samplerate, 180 audio_passthru); 181 Reconfigure(settings); 182 return (configured_audio_channels == 6); 183 } 184 185 186 186 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 187 { 188 188 AudioSettings settings = orig_settings; 189 189 190 int codec_id = CODEC_ID_NONE;191 int lcodec_id = CODEC_ID_NONE;192 int lcchannels = 0;193 int cchannels = 0;194 190 int lsource_audio_channels = settings.channels; 195 191 bool lneeds_upmix = false; 192 bool laudio_reenc = false; 196 193 197 if (settings.codec) 194 // Are we reencoding a (previously) timestretched bitstream? 195 if ((settings.codec == CODEC_ID_AC3 || settings.codec == CODEC_ID_DTS) && 196 !settings.use_passthru && allow_ac3_passthru) 198 197 { 199 lcodec_id = ((AVCodecContext*)settings.codec)->codec_id; 200 settings.bits = 16; 201 settings.channels = 2; 202 lsource_audio_channels = settings.channels; 203 settings.samplerate = 48000; 204 lcchannels = ((AVCodecContext*)settings.codec)->channels; 198 laudio_reenc = true; 199 VERBOSE(VB_AUDIO, LOC + "Reencoding decoded AC3/DTS to AC3"); 205 200 } 206 201 207 if (audio_codec) 202 // Enough channels? Upmix if not 203 if (settings.channels < configured_audio_channels && 204 !settings.use_passthru) 208 205 { 209 codec_id = audio_codec->codec_id;210 cchannels = ((AVCodecContext*)audio_codec)->channels;211 }212 213 if ((configured_audio_channels == 2) &&214 !(settings.codec || audio_codec) &&215 (settings.channels == 1))216 {217 206 settings.channels = configured_audio_channels; 218 207 lneeds_upmix = true; 219 VERBOSE(VB_AUDIO,LOC + "Needs Mono->Stereo upmix");220 }221 else if ((configured_audio_channels == 6) &&222 !(settings.codec || audio_codec))223 {224 settings.channels = configured_audio_channels;225 lneeds_upmix = true;226 208 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 227 209 } 228 210 … … 232 214 settings.samplerate == audio_samplerate && !need_resampler && 233 215 settings.use_passthru == audio_passthru && 234 216 lneeds_upmix == needs_upmix && 235 l codec_id == codec_id && lcchannels == cchannels);217 laudio_reenc == audio_reenc); 236 218 bool upmix_deps = 237 219 (lsource_audio_channels == source_audio_channels); 238 220 if (general_deps && upmix_deps) … … 259 241 waud = raud = 0; 260 242 audio_actually_paused = false; 261 243 262 bool redo_stretch = (pSoundStretch && audio_channels != settings.channels);263 244 audio_channels = settings.channels; 264 245 source_audio_channels = lsource_audio_channels; 265 246 audio_bits = settings.bits; 266 audio_samplerate = settings.samplerate; 267 audio_codec = (AVCodecContext*)settings.codec; 247 source_audio_samplerate = audio_samplerate = settings.samplerate; 248 audio_reenc = laudio_reenc; 249 audio_codec = settings.codec; 268 250 audio_passthru = settings.use_passthru; 269 251 needs_upmix = lneeds_upmix; 270 252 … … 273 255 Error("AudioOutput only supports 8 or 16bit audio."); 274 256 return; 275 257 } 276 audio_bytes_per_sample = audio_channels * audio_bits / 8; 277 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 258 259 VERBOSE(VB_AUDIO, LOC + QString("Original audio codec was %1") 260 .arg(codec_id_string((CodecID)audio_codec))); 278 261 279 262 need_resampler = false; 280 263 killaudio = false; … … 282 265 was_paused = true; 283 266 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 284 267 285 numlowbuffer = 0; 268 // Find out what sample rates we can output (if output layer supports it) 269 vector<int> rates = GetSupportedRates(); 270 vector<int>::iterator it; 271 bool resample = true; 286 272 287 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 273 for (it = rates.begin(); it < rates.end(); it++) 274 { 275 VERBOSE(VB_AUDIO, LOC + QString("Sample rate %1 is supported") 276 .arg(*it)); 277 if (*it == audio_samplerate) 278 resample = false; 279 } 280 281 // Assume 48k if we can't get supported rates 282 if (rates.empty()) 283 rates.push_back(48000); 284 285 if (resample) 286 { 287 int error; 288 audio_samplerate = *(rates.end()); 289 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 290 .arg(settings.samplerate).arg(audio_samplerate)); 291 src_ctx = src_new(2-src_quality, source_audio_channels, &error); 292 if (error) 293 { 294 Error(QString("Error creating resampler, the error was: %1") 295 .arg(src_strerror(error)) ); 296 src_ctx = NULL; 297 return; 298 } 299 src_data.src_ratio = (double) audio_samplerate / settings.samplerate; 300 src_data.data_in = src_in; 301 src_data.data_out = src_out; 302 src_data.output_frames = 16384*6; 303 need_resampler = true; 304 } 305 306 // Encode to AC-3 if not passing thru , there's > 2 channels 307 // and a passthru device is defined 308 if (!audio_passthru && allow_ac3_passthru && 309 (audio_channels > 2 || audio_reenc)) 310 { 311 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 312 encoder = new AudioOutputDigitalEncoder(); 313 if (!encoder->Init(CODEC_ID_AC3, 448000, audio_samplerate, audio_channels)) 314 { 315 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 316 delete encoder; 317 encoder = NULL; 318 } 319 320 audio_enc = true; 321 } 322 323 if(audio_passthru || audio_enc) 324 // AC-3 output - soundcard expects a 2ch 48k stream 325 audio_channels = 2; 326 327 audio_bytes_per_sample = audio_channels * audio_bits / 8; 328 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 329 330 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4 (reenc %5)") 288 331 .arg(audio_main_device).arg(audio_channels) 289 .arg(source_audio_channels).arg(audio_samplerate) );332 .arg(source_audio_channels).arg(audio_samplerate).arg(audio_reenc)); 290 333 291 334 // Actually do the device specific open call 292 335 if (!OpenDevice()) … … 298 341 return; 299 342 } 300 343 344 // Only used for software volume 345 if (set_initial_vol && internal_vol) 346 volume = gContext->GetNumSetting("PCMMixerVolume", 80); 347 { 348 QString controlLabel = gContext->GetSetting("MixerControl", "PCM"); 349 controlLabel += "MixerVolume"; 350 volume = gContext->GetNumSetting(controlLabel, 80); 351 } 352 301 353 SyncVolume(); 302 354 VolumeBase::UpdateVolume(); 303 355 304 356 VERBOSE(VB_AUDIO, LOC + QString("Audio fragment size: %1") 305 357 .arg(fragment_size)); 306 358 307 if (audio_buffer_unused < 0) 308 audio_buffer_unused = 0; 359 audio_buffer_unused = 0; 309 360 310 if (!gContext->GetNumSetting("AggressiveSoundcardBuffer", 0))311 audio_buffer_unused = 0;312 313 361 audbuf_timecode = 0; 314 362 audiotime = 0; 315 363 samples_buffered = 0; … … 318 366 current_seconds = -1; 319 367 source_bitrate = -1; 320 368 321 // NOTE: this won't do anything as above samplerate vars are set equal 322 // Check if we need the resampler 323 if (audio_samplerate != settings.samplerate) 369 if (needs_upmix) 324 370 { 325 int error;326 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")327 .arg(settings.samplerate).arg(audio_samplerate));328 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);329 if (error)330 {331 Error(QString("Error creating resampler, the error was: %1")332 .arg(src_strerror(error)) );333 return;334 }335 src_data.src_ratio = (double) audio_samplerate / settings.samplerate;336 src_data.data_in = src_in;337 src_data.data_out = src_out;338 src_data.output_frames = 16384*6;339 need_resampler = true;340 }341 342 if (needs_upmix &&343 !(settings.channels == 2))344 {345 371 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 346 372 if (configured_audio_channels == 6) 347 373 { … … 354 380 (FreeSurround::SurroundMode)surround_mode); 355 381 356 382 VERBOSE(VB_AUDIO, LOC + 357 QString(" create upmixer done with surround mode %1")383 QString("Create upmixer done with surround mode %1") 358 384 .arg(surround_mode)); 359 385 } 360 386 361 387 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 362 388 .arg(audio_stretchfactor)); 363 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")364 .arg((audio_codec) ?365 codec_id_string(audio_codec->codec_id) : "not set"));366 389 367 if (redo_stretch) 368 { 369 delete pSoundStretch; 370 pSoundStretch = NULL; 371 SetStretchFactorLocked(audio_stretchfactor); 372 } 373 else 374 { 375 SetStretchFactorLocked(audio_stretchfactor); 376 if (pSoundStretch) 377 { 378 // if its passthru then we need to reencode 379 if (audio_codec) 380 { 381 if (!encoder) 382 { 383 VERBOSE(VB_AUDIO, LOC + 384 QString("Creating Encoder for codec %1") 385 .arg(audio_codec->codec_id)); 386 387 encoder = new AudioOutputDigitalEncoder(); 388 if (!encoder->Init(audio_codec->codec_id, 389 audio_codec->bit_rate, 390 audio_codec->sample_rate, 391 audio_codec->channels 392 )) 393 { 394 // eeks 395 delete encoder; 396 encoder = NULL; 397 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 398 } 399 } 400 } 401 if (audio_codec && encoder) 402 { 403 pSoundStretch->setSampleRate(audio_codec->sample_rate); 404 pSoundStretch->setChannels(audio_codec->channels); 405 } 406 else 407 { 408 pSoundStretch->setSampleRate(audio_samplerate); 409 pSoundStretch->setChannels(audio_channels); 410 } 411 } 412 } 413 390 SetStretchFactorLocked(old_audio_stretchfactor); 391 414 392 // Setup visualisations, zero the visualisations buffers 415 393 prepareVisuals(); 416 394 … … 446 424 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 447 425 killaudio = true; 448 426 StopOutputThread(); 427 QMutexLocker lock1(&audio_buflock); 449 428 450 429 // Close resampler? 451 430 if (src_ctx) 431 { 452 432 src_delete(src_ctx); 433 src_ctx = NULL; 434 } 435 453 436 need_resampler = false; 454 437 455 438 // close sound stretcher … … 457 440 { 458 441 delete pSoundStretch; 459 442 pSoundStretch = NULL; 443 old_audio_stretchfactor = audio_stretchfactor; 444 audio_stretchfactor = 1.0; 460 445 } 461 446 462 447 if (encoder) … … 471 456 upmixer = NULL; 472 457 } 473 458 needs_upmix = false; 459 audio_enc = false; 474 460 475 461 CloseDevice(); 476 462 … … 621 607 622 608 // include algorithmic latencies 623 609 if (pSoundStretch) 624 {625 // add the effect of any unused but processed samples,626 // AC3 reencode does this627 totalbuffer += (int)(pSoundStretch->numSamples() *628 audio_bytes_per_sample);629 // add the effect of unprocessed samples in time stretch algo630 610 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 631 611 audio_bytes_per_sample) / audio_stretchfactor); 632 }633 612 634 613 if (upmixer && needs_upmix) 635 {636 614 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 637 }638 615 616 if (encoder) 617 totalbuffer += encoder->Buffered(); 618 639 619 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 640 620 (audio_bytes_per_sample * effdspstretched)); 641 621 … … 660 640 return audbuf_timecode - GetAudiotime(); 661 641 } 662 642 643 void AudioOutputBase::SetSWVolume(int new_volume, bool save) 644 { 645 volume = new_volume; 646 if (save) 647 { 648 QString controlLabel = gContext->GetSetting("MixerControl", "PCM"); 649 controlLabel += "MixerVolume"; 650 gContext->SaveSetting(controlLabel, volume); 651 } 652 } 653 654 int AudioOutputBase::GetSWVolume() 655 { 656 return volume; 657 } 658 659 void AudioOutputBase::AdjustVolume(void *buffer, int len, bool music) 660 { 661 if (audio_bits == 8) 662 _AdjustVolume<char>((char *)buffer, len, music); 663 else if (audio_bits == 16) 664 _AdjustVolume<short>((short *)buffer, len, music); 665 } 666 667 template <class AudioDataType> 668 void AudioOutputBase::_AdjustVolume(AudioDataType *buffer, int len, bool music) 669 { 670 float g = volume / 100.0; 671 672 // Should probably be exponential - this'll do 673 g *= g; 674 675 // Add gain to AC-3 - try to ~ match PCM volume 676 if (audio_enc && audio_reenc) 677 g *= 1.8; 678 679 // Music is relatively loud - ditto 680 else if (music) 681 g *= 0.4; 682 683 if (g == 1.0) 684 return; 685 686 for (int i = 0; i < (int)(len / sizeof(AudioDataType)); i++) 687 { 688 float s = static_cast<float>(buffer[i]) * g / 689 static_cast<float>(numeric_limits<AudioDataType>::max()); 690 if (s >= 1.0) 691 buffer[i] = numeric_limits<AudioDataType>::max(); 692 else if (s <= -1.0) 693 buffer[i] = numeric_limits<AudioDataType>::min(); 694 else 695 buffer[i] = static_cast<AudioDataType> 696 (s * numeric_limits<AudioDataType>::max()); 697 } 698 } 699 663 700 bool AudioOutputBase::AddSamples(char *buffers[], int samples, 664 701 long long timecode) 665 702 { … … 691 728 return false; // would overflow 692 729 } 693 730 731 QMutexLocker lock1(&audio_buflock); 732 694 733 // resample input if necessary 695 734 if (need_resampler && src_ctx) 696 735 { … … 735 774 int abps = (encoder) ? 736 775 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 737 776 int len = samples * abps; 777 778 // Give original samples to mythmusic visualisation 779 dispatchVisual((unsigned char *)buffer, len, timecode, 780 source_audio_channels, audio_bits); 738 781 739 782 // Check we have enough space to write the data 740 783 if (need_resampler && src_ctx) … … 759 802 return false; // would overflow 760 803 } 761 804 805 QMutexLocker lock1(&audio_buflock); 806 762 807 // resample input if necessary 763 808 if (need_resampler && src_ctx) 764 809 { … … 819 864 { 820 865 int error = src_reset(src_ctx); 821 866 if (error) 867 { 822 868 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 823 869 "Error occurred while resetting resampler: %1") 824 870 .arg(src_strerror(error))); 871 src_ctx = NULL; 872 } 825 873 } 826 874 } 827 875 } … … 852 900 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 853 901 long long timecode) 854 902 { 855 audio_buflock.lock();856 857 903 int len; // = samples * audio_bytes_per_sample; 858 904 int audio_bytes = audio_bits / 8; 859 905 int org_waud = waud; … … 870 916 .arg(samples * abps) 871 917 .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode) 872 918 .arg(needs_upmix)); 873 919 874 920 len = WaitForFreeSpace(samples); 875 921 876 922 if (needs_upmix && 877 923 configured_audio_channels == 2 && 878 924 source_audio_channels == 1) … … 893 939 else if (upmixer && needs_upmix) 894 940 { 895 941 int out_samples = 0; 942 org_waud = waud; 896 943 int step = (interleaved)?source_audio_channels:1; 897 944 898 945 for (int itemp = 0; itemp < samples; ) 899 946 { 900 // just in case it does a processing cycle, release the lock901 // to allow the output loop to do output902 audio_buflock.unlock();903 947 if (audio_bytes == 2) 904 948 { 905 949 itemp += upmixer->putSamples( … … 916 960 source_audio_channels, 917 961 (interleaved) ? 0 : samples); 918 962 } 919 audio_buflock.lock();920 963 921 964 int copy_samples = upmixer->numSamples(); 922 965 if (copy_samples) … … 942 985 org_waud = (org_waud + copy_len) % kAudioRingBufferSize; 943 986 } 944 987 } 945 946 988 if (samples > 0) 947 989 len = WaitForFreeSpace(out_samples); 948 990 … … 984 1026 } 985 1027 } 986 1028 987 if (samples > 0) 1029 if (samples <= 0) 1030 return; 1031 1032 if (pSoundStretch) 988 1033 { 989 if (pSoundStretch) 1034 // does not change the timecode, only the number of samples 1035 // back to orig pos 1036 org_waud = waud; 1037 int bdiff = kAudioRingBufferSize - org_waud; 1038 int nSamplesToEnd = bdiff/abps; 1039 if (bdiff < len) 990 1040 { 1041 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1042 (audiobuffer + 1043 org_waud), nSamplesToEnd); 1044 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 1045 (len - bdiff) / abps); 1046 } 1047 else 1048 { 1049 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1050 (audiobuffer + org_waud), 1051 len / abps); 1052 } 991 1053 992 // does not change the timecode, only the number of samples 993 // back to orig pos 994 org_waud = waud; 995 int bdiff = kAudioRingBufferSize - org_waud; 996 int nSamplesToEnd = bdiff/abps; 997 if (bdiff < len) 998 { 999 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1000 (audiobuffer + 1001 org_waud), nSamplesToEnd); 1002 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 1003 (len - bdiff) / abps); 1054 int nSamples = pSoundStretch->numSamples(); 1055 len = WaitForFreeSpace(nSamples); 1056 1057 while ((nSamples = pSoundStretch->numSamples())) 1058 { 1059 if (nSamples > nSamplesToEnd) 1060 nSamples = nSamplesToEnd; 1061 1062 nSamples = pSoundStretch->receiveSamples( 1063 (soundtouch::SAMPLETYPE*) 1064 (audiobuffer + org_waud), nSamples 1065 ); 1066 1067 if (nSamples == nSamplesToEnd) { 1068 org_waud = 0; 1069 nSamplesToEnd = kAudioRingBufferSize/abps; 1004 1070 } 1005 else 1006 { 1007 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 1008 (audiobuffer + org_waud), 1009 len / abps); 1071 else { 1072 org_waud += nSamples * abps; 1073 nSamplesToEnd -= nSamples; 1010 1074 } 1075 } 1076 } 1011 1077 1012 if (encoder) 1013 { 1014 // pull out a packet's worth and reencode it until we 1015 // don't have enough for any more packets 1016 soundtouch::SAMPLETYPE *temp_buff = 1017 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1018 size_t frameSize = encoder->FrameSize()/abps; 1078 if (internal_vol && SWVolume()) 1079 { 1080 int bdiff = kAudioRingBufferSize - waud; 1081 bool music = (timecode < 1); 1019 1082 1020 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 1021 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1022 .arg(frameSize) 1023 .arg(encoder->FrameSize()) 1024 .arg(pSoundStretch->numSamples())); 1025 1026 // process the same number of samples as it creates 1027 // a full encoded buffer just like before 1028 while (pSoundStretch->numSamples() >= frameSize) 1029 { 1030 int got = pSoundStretch->receiveSamples( 1031 temp_buff, frameSize); 1032 int amount = encoder->Encode(temp_buff); 1033 1034 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 1035 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1036 .arg(amount) 1037 .arg(got) 1038 .arg(pSoundStretch->numSamples())); 1039 1040 if (!amount) 1041 continue; 1042 1043 //len = WaitForFreeSpace(amount); 1044 char *ob = encoder->GetOutBuff(); 1045 if (amount >= bdiff) 1046 { 1047 memcpy(audiobuffer + org_waud, ob, bdiff); 1048 ob += bdiff; 1049 amount -= bdiff; 1050 org_waud = 0; 1051 } 1052 if (amount > 0) 1053 memcpy(audiobuffer + org_waud, ob, amount); 1054 1055 bdiff = kAudioRingBufferSize - amount; 1056 org_waud = (org_waud + amount) % kAudioRingBufferSize; 1057 } 1058 } 1059 else 1060 { 1061 int newLen = 0; 1062 int nSamples; 1063 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1064 audio_bytes_per_sample); 1065 do 1066 { 1067 int samplesToGet = len/audio_bytes_per_sample; 1068 if (samplesToGet > nSamplesToEnd) 1069 { 1070 samplesToGet = nSamplesToEnd; 1071 } 1072 1073 nSamples = pSoundStretch->receiveSamples( 1074 (soundtouch::SAMPLETYPE*) 1075 (audiobuffer + org_waud), samplesToGet); 1076 if (nSamples == nSamplesToEnd) 1077 { 1078 org_waud = 0; 1079 nSamplesToEnd = kAudioRingBufferSize/audio_bytes_per_sample; 1080 } 1081 else 1082 { 1083 int bufsz = nSamples * audio_bytes_per_sample; 1084 org_waud = (org_waud + bufsz) % kAudioRingBufferSize; 1085 nSamplesToEnd -= nSamples; 1086 } 1087 1088 newLen += nSamples * audio_bytes_per_sample; 1089 len -= nSamples * audio_bytes_per_sample; 1090 } while (nSamples > 0); 1091 } 1083 if (bdiff < len) 1084 { 1085 AdjustVolume(audiobuffer + waud, bdiff, music); 1086 AdjustVolume(audiobuffer, len - bdiff, music); 1092 1087 } 1088 else 1089 AdjustVolume(audiobuffer + waud, len, music); 1090 } 1093 1091 1094 waud = org_waud; 1095 lastaudiolen = audiolen(false); 1092 // Encode to AC-3? 1093 if (encoder) 1094 { 1095 org_waud = waud; 1096 int bdiff = kAudioRingBufferSize - org_waud; 1097 int to_get = 0; 1096 1098 1097 if ( timecode < 0)1099 if (bdiff < len) 1098 1100 { 1099 // mythmusic doesn't give timestamps..1100 t imecode = (int)((samples_buffered * 100000.0) / effdsp);1101 encoder->Encode(audiobuffer + org_waud, bdiff); 1102 to_get = encoder->Encode(audiobuffer, len - bdiff); 1101 1103 } 1102 1103 samples_buffered += samples; 1104 1105 /* we want the time at the end -- but the file format stores 1106 time at the start of the chunk. */ 1107 // even with timestretch, timecode is still calculated from original 1108 // sample count 1109 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1104 else 1105 to_get = encoder->Encode(audiobuffer + org_waud, len); 1110 1106 1111 if ( interleaved)1107 if (to_get > 0) 1112 1108 { 1113 dispatchVisual((unsigned char *)buffer, len, timecode, 1114 source_audio_channels, audio_bits); 1109 if (to_get >= bdiff) 1110 { 1111 encoder->GetFrames(audiobuffer + org_waud, bdiff); 1112 to_get -= bdiff; 1113 org_waud = 0; 1114 } 1115 if (to_get > 0) 1116 encoder->GetFrames(audiobuffer + org_waud, to_get); 1117 1118 org_waud += to_get; 1115 1119 } 1116 1120 } 1117 1121 1118 audio_buflock.unlock(); 1122 waud = org_waud; 1123 lastaudiolen = audiolen(false); 1124 1125 if (timecode < 0) 1126 // mythmusic doesn't give timestamps.. 1127 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1128 1129 samples_buffered += samples; 1130 1131 /* we want the time at the end -- but the file format stores 1132 time at the start of the chunk. */ 1133 // even with timestretch, timecode is still calculated from original 1134 // sample count 1135 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1119 1136 } 1120 1137 1121 1138 void AudioOutputBase::Status() … … 1256 1273 last_space_on_soundcard = space_on_soundcard; 1257 1274 } 1258 1275 1259 numlowbuffer++;1260 if (numlowbuffer > 5 && audio_buffer_unused)1261 {1262 VERBOSE(VB_IMPORTANT, LOC + "dropping back audio_buffer_unused");1263 audio_buffer_unused /= 2;1264 }1265 1266 1276 usleep(5000); 1267 1277 continue; 1268 1278 } 1269 else1270 numlowbuffer = 0;1271 1279 1272 1280 Status(); 1273 1281 -
mythtv/libs/libmyth/audiooutput.cpp
31 31 AudioOutput *AudioOutput::OpenAudio( 32 32 const QString &main_device, 33 33 const QString &passthru_device, 34 int audio_bits, int audio_channels, int audio_samplerate, 34 int audio_bits, int audio_channels, 35 int audio_codec, int audio_samplerate, 35 36 AudioOutputSource source, 36 bool set_initial_vol, bool audio_passthru) 37 bool set_initial_vol, bool audio_passthru, 38 int upmixer_startup) 37 39 { 38 40 AudioSettings settings( 39 41 main_device, passthru_device, audio_bits, 40 audio_channels, audio_ samplerate, source,41 set_initial_vol, audio_passthru );42 audio_channels, audio_codec, audio_samplerate, source, 43 set_initial_vol, audio_passthru, upmixer_startup); 42 44 43 45 settings.FixPassThrough(); 44 46 -
mythtv/libs/libmyth/audiosettings.h
29 29 const QString &audio_passthru_device, 30 30 int audio_bits, 31 31 int audio_channels, 32 int audio_codec, 32 33 int audio_samplerate, 33 34 AudioOutputSource audio_source, 34 35 bool audio_set_initial_vol, 35 36 bool audio_use_passthru, 36 void *audio_codec = NULL);37 int upmixer_startup = 0); 37 38 38 39 AudioSettings(int audio_bits, 39 40 int audio_channels, 41 int audio_codec, 40 42 int audio_samplerate, 41 43 bool audio_use_passthru, 42 void *audio_codec = NULL);44 int upmixer_startup = 0); 43 45 44 46 void FixPassThrough(void); 45 47 void TrimDeviceType(void); … … 54 56 public: 55 57 int bits; 56 58 int channels; 59 int codec; 57 60 int samplerate; 58 61 bool set_initial_vol; 59 62 bool use_passthru; 60 void *codec;61 63 AudioOutputSource source; 64 int upmixer; 62 65 }; 63 66 64 67 #endif // _AUDIO_SETTINGS_H_ -
mythtv/libs/libmyth/volumebase.h
20 20 VolumeBase(); 21 21 virtual ~VolumeBase() {}; 22 22 23 void SWVolume(bool set); 24 bool SWVolume(void); 23 25 virtual uint GetCurrentVolume(void) const; 24 26 virtual void SetCurrentVolume(int value); 25 27 virtual void AdjustCurrentVolume(int change); … … 34 36 35 37 virtual int GetVolumeChannel(int channel) const = 0; // Returns 0-100 36 38 virtual void SetVolumeChannel(int channel, int volume) = 0; // range 0-100 for vol 39 virtual void SetSWVolume(int new_volume, bool save) = 0; 40 virtual int GetSWVolume(void) = 0; 37 41 38 42 void UpdateVolume(void); 39 43 void SyncVolume(void); … … 44 48 45 49 int volume; 46 50 MuteState current_mute_state; 51 bool swvol; 52 bool swvol_setting; 47 53 48 54 }; 49 55 -
mythtv/libs/libmyth/audiooutputoss.cpp
42 42 KillAudio(); 43 43 } 44 44 45 vector<int> AudioOutputOSS::GetSupportedRates() 46 { 47 const int srates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000 }; 48 vector<int> rates(srates, srates + sizeof(srates) / sizeof(int) ); 49 audiofd = open(audio_main_device.toAscii(), O_WRONLY | O_NONBLOCK); 50 51 if (audiofd < 0) 52 { 53 VERBOSE(VB_IMPORTANT, QString("Error opening audio device (%1), the" 54 " error was: %2").arg(audio_main_device).arg(strerror(errno))); 55 rates.clear(); 56 return rates; 57 } 58 59 vector<int>::iterator it = rates.begin(); 60 61 while (it != rates.end()) 62 { 63 if(ioctl(audiofd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0) 64 it = rates.erase(it); 65 else 66 it++; 67 } 68 69 close(audiofd); 70 audiofd = -1; 71 72 return rates; 73 } 74 45 75 bool AudioOutputOSS::OpenDevice() 46 76 { 47 77 numbadioctls = 0; … … 287 317 int volume = 0; 288 318 289 319 QString device = gContext->GetSetting("MixerDevice", "/dev/mixer"); 320 if (device.toLower() == "software") 321 return; 322 290 323 QByteArray dev = device.toAscii(); 291 324 mixerfd = open(dev.constData(), O_RDONLY); 292 325 -
mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
32 32 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 33 33 audio_bytes_per_sample(0), 34 34 av_context(NULL), 35 outbuf(NULL), 36 outbuf_size(0), 37 frame_buffer(NULL), 35 outbuflen(0), 36 inbuflen(0), 38 37 one_frame_bytes(0) 39 38 { 40 39 } … … 52 51 av_free(av_context); 53 52 av_context = NULL; 54 53 } 55 56 if (outbuf)57 {58 delete [] outbuf;59 outbuf = NULL;60 outbuf_size = 0;61 }62 63 if (frame_buffer)64 {65 delete [] frame_buffer;66 frame_buffer = NULL;67 one_frame_bytes = 0;68 }69 54 } 70 55 71 56 //CODEC_ID_AC3 … … 81 66 .arg(samplerate) 82 67 .arg(channels)); 83 68 84 //codec = avcodec_find_encoder(codec_id); 69 // We need to do this when called from mythmusic 70 avcodec_init(); 71 avcodec_register_all(); 85 72 // always AC3 as there is no DTS encoder at the moment 2005/1/9 86 73 codec = avcodec_find_encoder(CODEC_ID_AC3); 87 74 if (!codec) … … 110 97 audio_bytes_per_sample = bytes_per_frame; 111 98 one_frame_bytes = bytes_per_frame * av_context->frame_size; 112 99 113 outbuf_size = 16384; // ok for AC3 but DTS?114 outbuf = new char [outbuf_size];115 100 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 116 101 .arg(av_context->frame_size) 117 102 .arg(bytes_per_frame) … … 259 244 static int encode_frame( 260 245 bool dts, 261 246 unsigned char *data, 262 size_t &len)247 size_t enc_len) 263 248 { 264 249 unsigned char *payload = data + 8; // skip header, currently 52 or 54bits 265 size_t enc_len;266 250 int flags, sample_rate, bit_rate; 267 251 268 252 // we don't do any length/crc validation of the AC3 frame here; presumably … … 273 257 // ignore, and if so, may as well just assume that it will ignore 274 258 // anything with a bad CRC... 275 259 276 uint nr_samples = 0, block_len; 260 uint nr_samples = 0, block_len = 0; 261 277 262 if (dts) 278 263 { 279 264 enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate); … … 302 287 } 303 288 } 304 289 305 if (enc_len == 0 || enc_len > len)306 {307 int l = len;308 len = 0;309 return l;310 }311 312 290 enc_len = std::min((uint)enc_len, block_len - 8); 313 291 314 292 //uint32_t x = *(uint32_t*)payload; … … 361 339 data[6] = (enc_len << 3) & 0xFF; 362 340 data[7] = (enc_len >> 5) & 0xFF; 363 341 memset(payload + enc_len, 0, block_len - 8 - enc_len); 364 len = block_len;365 342 366 343 return enc_len; 367 344 } 368 345 369 // must have exactly 1 frames worth of data 370 size_t AudioOutputDigitalEncoder::Encode(short *buff) 346 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 371 347 { 372 int encsize = 0;373 348 size_t outsize = 0; 374 375 // put data in the correct spot for encode frame376 outsize = avcodec_encode_audio(377 av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff);378 349 379 size_t tmpsize = outsize; 350 int fs = FrameSize(); 351 memcpy(inbuf+inbuflen, buf, len); 352 inbuflen += len; 353 int frames = inbuflen / fs; 380 354 381 outsize = MAX_AC3_FRAME_SIZE; 382 encsize = encode_frame( 383 /*av_context->codec_id==CODEC_ID_DTS*/ false, 384 (unsigned char*)outbuf, outsize); 355 while (frames--) 356 { 357 // put data in the correct spot for encode frame 358 outsize = avcodec_encode_audio( 359 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 385 360 386 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 387 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 388 .arg(tmpsize).arg(encsize).arg(outsize)); 361 encode_frame( 362 /*av_context->codec_id==CODEC_ID_DTS*/ false, 363 (unsigned char*)outbuf + outbuflen, outsize 364 ); 389 365 390 return outsize; 366 outbuflen += MAX_AC3_FRAME_SIZE; 367 inbuflen -= fs; 368 memmove(inbuf, inbuf+fs, inbuflen); 369 } 370 371 return outbuflen; 391 372 } 373 374 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 375 { 376 int len = (maxlen < outbuflen ? maxlen : outbuflen); 377 memcpy(ptr, outbuf, len); 378 outbuflen -= len; 379 memmove(outbuf, outbuf+len, outbuflen); 380 } -
mythtv/libs/libmyth/audiooutput.h
15 15 static AudioOutput *OpenAudio( 16 16 const QString &audiodevice, 17 17 const QString &passthrudevice, 18 int audio_bits, int audio_channels, int audio_samplerate, 18 int audio_bits, int audio_channels, 19 int audio_codec, int audio_samplerate, 19 20 AudioOutputSource source, 20 bool set_initial_vol, bool audio_passthru); 21 bool set_initial_vol, bool audio_passthru, 22 int upmixer_startup = 0); 21 23 22 24 AudioOutput() : 23 25 VolumeBase(), OutputListeners(), … … 68 70 69 71 virtual void bufferOutputData(bool y) = 0; 70 72 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 73 virtual bool ToggleUpmix(void) = 0; 71 74 72 75 protected: 73 76 void Error(const QString &msg); -
mythtv/libs/libmyth/audiooutputdigitalencoder.h
5 5 #include "libavcodec/avcodec.h" 6 6 }; 7 7 8 #define INBUFSIZE 131072 9 #define OUTBUFSIZE 98304 10 8 11 class AudioOutputDigitalEncoder 9 12 { 10 13 public: … … 13 16 14 17 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 15 18 void Dispose(void); 16 size_t Encode(short * buff); 17 18 inline char *GetFrameBuffer(void); 19 size_t Encode(void *buf, int len); 20 void GetFrames(void *ptr, int maxlen); 19 21 size_t FrameSize(void) const { return one_frame_bytes; } 20 char *GetOutBuff(void) const { return outbuf;}22 int Buffered(void) const { return inbuflen; } 21 23 22 24 public: 23 25 size_t audio_bytes_per_sample; 24 26 25 27 private: 26 28 AVCodecContext *av_context; 27 char *outbuf; 28 int outbuf_size; 29 char *frame_buffer; 29 char outbuf[OUTBUFSIZE]; 30 char inbuf[INBUFSIZE]; 31 int outbuflen; 32 int inbuflen; 30 33 size_t one_frame_bytes; 31 34 }; 32 35 33 inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void)34 {35 if (!frame_buffer && av_context)36 frame_buffer = new char [one_frame_bytes];37 38 return frame_buffer;39 }40 41 36 #endif -
mythtv/libs/libmyth/audiooutputalsa.h
65 65 virtual void WriteAudio(unsigned char *aubuf, int size); 66 66 virtual int GetSpaceOnSoundcard(void) const; 67 67 virtual int GetBufferedOnSoundcard(void) const; 68 vector<int> GetSupportedRates(void); 68 69 69 70 private: 71 void SetIECStatus(bool audio); 70 72 inline int SetParameters(snd_pcm_t *handle, 71 73 snd_pcm_format_t format, unsigned int channels, 72 74 unsigned int rate, unsigned int buffer_time, -
mythtv/libs/libmythfreesurround/el_processor.cpp
26 26 #include "fftw3.h" 27 27 #else 28 28 extern "C" { 29 #include "libavutil/declare_aligned.h"30 29 #include "dsputil.h" 31 30 }; 32 31 typedef FFTSample FFTComplexArray[2]; … … 41 40 42 41 const float PI = 3.141592654; 43 42 const float epsilon = 0.000001; 44 //const float center_level = 0.5*sqrt(0.5); // gain of the center channel 45 //const float center_level = sqrt(0.5); // gain of the center channel 46 const float center_level = 1.0; // gain of the center channel 47 //const float center_level = 0.5; // gain of the center channel 43 const float center_level = 0.5*sqrt(0.5); 48 44 49 // should be .6-.750 // but with centerlevel 2x what its supposed to be, we halve 0.6851 // to keep center from clipping52 //const float window_gain = 0.34;53 //const float window_gain = 0.68;54 const float window_gain = 0.95; // to prive a bit of margin55 56 45 // private implementation of the surround decoder 57 46 class decoder_impl { 58 47 public: … … 99 88 outbuf[c].resize(N); 100 89 filter[c].resize(N); 101 90 } 102 // DC component of filters is always 0103 for (unsigned c=0;c<5;c++)104 {105 filter[c][0] = 0.0;106 filter[c][1] = 0.0;107 filter[c][halfN] = 0.0;108 }109 91 sample_rate(48000); 110 92 // generate the window function (square root of hann, b/c it is applied before and after the transform) 111 93 wnd.resize(N); 112 // dft normalization included in the window for zero cost scaling 113 // also add a gain factor of *2 due to processing gain in algo (see center_level) 114 surround_gain(1.0); 94 for (unsigned k=0;k<N;k++) 95 wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N); 115 96 current_buf = 0; 116 97 memset(inbufs, 0, sizeof(inbufs)); 117 98 memset(outbufs, 0, sizeof(outbufs)); … … 195 176 // set lfe filter params 196 177 void sample_rate(unsigned int srate) { 197 178 // lfe filter is just straight through band limited 198 unsigned int cutoff = ( 250*N)/srate;179 unsigned int cutoff = (30*N)/srate; 199 180 for (unsigned f=0;f<=halfN;f++) { 200 if ( (f>=2) && (f<cutoff))201 filter[5][f] = 1.0;181 if (f<cutoff) 182 filter[5][f] = 0.5*sqrt(0.5); 202 183 else 203 184 filter[5][f] = 0.0; 204 185 } … … 217 198 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 218 199 } 219 200 220 void surround_gain(float gain) {221 master_gain = gain * window_gain * 0.5 * 0.25;222 for (unsigned k=0;k<N;k++)223 wnd[k] = sqrt(master_gain*(1-cos(2*PI*k/N))/N);224 }225 226 201 // set the phase shifting mode 227 202 void phase_mode(unsigned mode) { 228 203 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; … … 293 268 294 269 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 295 270 // but dont do DC or N/2 component 296 for (unsigned f= 2;f<halfN;f++) {271 for (unsigned f=0;f<halfN;f++) { 297 272 // get left/right amplitudes/phases 298 273 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 299 274 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); … … 308 283 phaseDiff = abs(phaseDiff); 309 284 310 285 if (linear_steering) { 311 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);312 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */313 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();314 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);315 316 /*317 Problem:318 This assumes that the values are interpolated linearly between the cardinal points.319 But this way we have no chance of knowing the average volume...320 - Can we solve that computing everything under the assumption of normalized volume?321 No. Seemingly not.322 - Maybe we should add w explitcitly into the equation and see if we can solve it...323 */324 325 326 //cfloat lt(0.5,0),rt(0.5,0);327 //cfloat x(0,0), y(1,0);328 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);329 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);330 cfloat s = sqrt(p*p/4.0f - q);331 cfloat x = -p;332 cfloat x1 = -p/2.0f + s;333 cfloat x2 = -p/2.0f - s;334 float x = 0;335 if (x1.real() >= -1 && x1.real() <= 1)336 x = x1.real();337 else if (x2.real() >= -1 && x2.real() <= 1)338 x = x2.real();*/339 340 //cfloat yp = (rt - (x*E+H))/(F+x*G);341 //cfloat xp = (lt - (y*B+D))/(A+y*C);342 343 /*xfs[f] = x;344 yfs[f] = y.real();*/345 346 286 // --- this is the fancy new linear mode --- 347 287 348 288 // get sound field x/y position … … 600 540 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 601 541 float surround_balance; // the xfs balance that follows from the coeffs 602 542 float surround_level; // gain for the surround channels (follows from the coeffs 603 float master_gain; // gain for all channels604 543 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 605 544 float front_separation; // front stereo separation 606 545 float rear_separation; // rear stereo separation … … 628 567 629 568 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 630 569 631 void fsurround_decoder::gain(float gain) { impl->surround_gain(gain); }632 633 570 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 634 571 635 572 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); } -
mythtv/libs/libmythfreesurround/freesurround.cpp
63 63 const unsigned default_block_size = 8192; 64 64 // there will be a slider for this in the future 65 65 //const float master_gain = 1.0; 66 //#define MASTER_GAIN * master_gain 66 //#define MASTER_GAIN * master_gain 67 67 #define MASTER_GAIN 68 //const float master_gain = 1.0/(1<<15); 69 //const float inv_master_gain = (1<<15); 68 //const float inv_master_gain = 1.0; 70 69 //#define INV_MASTER_GAIN * inv_master_gain 71 70 #define INV_MASTER_GAIN 72 71 … … 192 191 if (moviemode) 193 192 { 194 193 params.phasemode = 1; 195 params.center_width = 0;196 params. gain = 1.0;194 params.center_width = 25; 195 params.dimension = 0.5; 197 196 } 198 197 else 199 198 { 200 params.center_width = 70; 201 // for 50, gain should be about 1.9, c/lr about 2.7 202 // for 70, gain should be about 3.1, c/lr about 1.5 203 params.gain = 3.1; 199 params.center_width = 65; 200 params.dimension = 0.3; 204 201 } 205 202 switch (surround_mode) 206 203 { … … 236 233 decoder->phase_mode(params.phasemode); 237 234 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 238 235 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 239 decoder->gain(params.gain);240 236 } 241 237 } 242 238 … … 250 246 phasemode(0), 251 247 steering(1), 252 248 front_sep(100), 253 rear_sep(100), 254 gain(1.0) 249 rear_sep(100) 255 250 { 256 251 } 257 252 … … 581 576 uint oc = out_count; 582 577 if (maxSamples>oc) maxSamples = oc; 583 578 uint outindex = processed_size - oc; 579 584 580 switch (surround_mode) 585 581 { 586 582 case SurroundModePassive: … … 655 651 { 656 652 if (decoder) 657 653 { 658 // actually these params need only be set when they change... but it doesn't hurt659 #if 0660 decoder->steering_mode(params.steering);661 decoder->phase_mode(params.phasemode);662 decoder->surround_coefficients(params.coeff_a, params.coeff_b);663 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);664 #endif665 // decode the bufs->block666 //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);667 //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);668 654 decoder->decode(params.center_width/100.0,params.dimension/100.0); 669 655 } 670 656 } -
mythtv/libs/libmythfreesurround/el_processor.h
47 47 // a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right. 48 48 void surround_coefficients(float a, float b); 49 49 50 // override for master surround gain51 void gain(float gain);52 53 50 // set the phase shifting mode for decoding 54 // 0 = (+0 °,+0°) - music mode55 // 1 = (+0 °,+180°) - PowerDVD compatibility56 // 2 = (+180 °,+0°) - BeSweet compatibility57 // 3 = (-90 °,+90°) - This seems to work. I just don't know why.51 // 0 = (+0,+0) - music mode 52 // 1 = (+0,+180) - PowerDVD compatibility 53 // 2 = (+180,+0) - BeSweet compatibility 54 // 3 = (-90,+90) - This seems to work. I just don't know why. 58 55 void phase_mode(unsigned mode); 59 56 60 57 // override the steering mode -
mythtv/programs/mythfrontend/globalsettings.cpp
91 91 static HostComboBox *MaxAudioChannels() 92 92 { 93 93 HostComboBox *gc = new HostComboBox("MaxChannels",false); 94 gc->setLabel(QObject::tr(" Max Audio Channels"));94 gc->setLabel(QObject::tr("Speakers configuration")); 95 95 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 96 96 gc->addSelection(QObject::tr("5.1"), "6"); 97 97 gc->setHelpText( 98 98 QObject::tr( 99 "Set the maximum number of audio channels to be decoded. " 100 "This is for multi-channel/surround audio playback.")); 99 "Set your audio configuration: Stereo or Surround.")); 101 100 return gc; 102 101 } 103 102 103 static HostCheckBox *AudioUpmix() 104 { 105 HostCheckBox *gc = new HostCheckBox("AudioDefaultUpmix"); 106 gc->setLabel(QObject::tr("Upconvert stereo to 5.1 surround")); 107 gc->setValue(true); 108 gc->setHelpText(QObject::tr("MythTV can upconvert stereo to 5.1 audio. " 109 "Set this option to enable it by default. " 110 "You can enable or disable the upconversion during playback at anytime.")); 111 return gc; 112 } 113 104 114 static HostComboBox *AudioUpmixType() 105 115 { 106 116 HostComboBox *gc = new HostComboBox("AudioUpmixType",false); 107 117 gc->setLabel(QObject::tr("Upmix")); 108 gc->addSelection(QObject::tr(" Passive"), "0", true); // default109 gc->addSelection(QObject::tr(" Active Simple"), "1");110 gc->addSelection(QObject::tr(" Active Linear"), "2");118 gc->addSelection(QObject::tr("Fastest"), "0", true); // default 119 gc->addSelection(QObject::tr("Good"), "1"); 120 gc->addSelection(QObject::tr("Best"), "2"); 111 121 gc->setHelpText( 112 122 QObject::tr( 113 "Set the audio upmix type for 2ch to 6ch conversion. " 114 "This is for multi-channel/surround audio playback. " 115 "'Passive' is the least demanding on the CPU. " 116 "'Active Simple' is more demanding and 'Active Linear' " 117 "is the most demanding (but highest quality).")); 123 "Set the audio surround upconversion quality. " 124 "'Fastest' is the least demanding on the CPU at the expense of quality.")); 118 125 return gc; 119 126 } 120 127 … … 122 129 { 123 130 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); 124 131 125 gc->setLabel(QObject::tr(" Passthroughoutput device"));132 gc->setLabel(QObject::tr("Digital output device")); 126 133 gc->addSelection(QObject::tr("Default"), "Default"); 127 134 #ifndef USING_MINGW 128 135 gc->addSelection("ALSA:iec958:{ AES0 0x02 }", "ALSA:iec958:{ AES0 0x02 }"); … … 130 137 gc->addSelection("ALSA:plughw:0,3", "ALSA:plughw:0,3"); 131 138 #endif 132 139 133 gc->setHelpText(QObject::tr("Audio output device to use for AC3 and " 134 "DTS passthrough. Default is the same as Audio output " 140 gc->setHelpText(QObject::tr("Audio output device to use for digital audio. Default is the same as Audio output " 135 141 "device. This value is currently only used with ALSA " 136 142 "sound output.")); 137 143 return gc; … … 143 149 gc->setLabel(QObject::tr("Use internal volume controls")); 144 150 gc->setValue(true); 145 151 gc->setHelpText(QObject::tr("MythTV can control the PCM and master " 146 "mixer volume. If you prefer to use an external mixer " 147 "program, then disable this option.")); 152 "mixer volume. If you prefer to control the volume externally " 153 "(like your amplifier) or use an external mixer " 154 "program, disable this option.")); 148 155 return gc; 149 156 } 150 157 … … 170 177 gc->addSelection("DirectX:", "DirectX:"); 171 178 gc->addSelection("Windows:", "Windows:"); 172 179 #endif 180 #if !defined(USING_MINGW) 181 gc->addSelection("software", "software"); 182 gc->setHelpText(QObject::tr("Setting the mixer device to \"software\" lets MythTV control " 183 "the volume of all audio at the expense of a slight quality loss.")); 184 #endif 173 185 174 186 return gc; 175 187 } … … 230 242 static HostCheckBox *AC3PassThrough() 231 243 { 232 244 HostCheckBox *gc = new HostCheckBox("AC3PassThru"); 233 gc->setLabel(QObject::tr(" Enable AC3 to SPDIF passthrough"));245 gc->setLabel(QObject::tr("Dolby Digital")); 234 246 gc->setValue(false); 235 gc->setHelpText(QObject::tr("Enable sending AC3 audio directly to your " 236 "sound card's SPDIF output, on sources which contain " 237 "AC3 soundtracks (usually digital TV). Requires that " 238 "the audio output device be set to something suitable.")); 247 gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder supports AC3/Dolby Digital. " 248 "You must use a digital connection. Uncheck if using an analog connection.")); 239 249 return gc; 240 250 } 241 251 242 252 static HostCheckBox *DTSPassThrough() 243 253 { 244 254 HostCheckBox *gc = new HostCheckBox("DTSPassThru"); 245 gc->setLabel(QObject::tr(" Enable DTS to SPDIF passthrough"));255 gc->setLabel(QObject::tr("DTS")); 246 256 gc->setValue(false); 247 gc->setHelpText(QObject::tr("Enable sending DTS audio directly to your " 248 "sound card's SPDIF output, on sources which contain " 249 "DTS soundtracks (usually DVDs). Requires that the " 250 "audio output device be set to something suitable.")); 257 gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder supports DTS. " 258 "You must use a digital connection. Uncheck if using an analog connection")); 251 259 return gc; 252 260 } 253 261 … … 1958 1966 return gc; 1959 1967 } 1960 1968 1961 static HostCheckBox *AggressiveBuffer()1962 {1963 HostCheckBox *gc = new HostCheckBox("AggressiveSoundcardBuffer");1964 gc->setLabel(QObject::tr("Aggressive Sound card Buffering"));1965 gc->setValue(false);1966 gc->setHelpText(QObject::tr("If enabled, MythTV will pretend to have "1967 "a smaller sound card buffer than is really present. This "1968 "may speed up seeking, but can also cause playback "1969 "problems."));1970 return gc;1971 }1972 1973 1969 static HostCheckBox *ClearSavedPosition() 1974 1970 { 1975 1971 HostCheckBox *gc = new HostCheckBox("ClearSavedPosition"); … … 3467 3463 return gs; 3468 3464 } 3469 3465 3470 class AudioSystemSettingsGroup : public VerticalConfigurationGroup3466 class AudioSystemSettingsGroup : public TriggeredConfigurationGroup 3471 3467 { 3472 3468 public: 3473 3469 AudioSystemSettingsGroup() : 3474 VerticalConfigurationGroup(false, true, false, false)3470 TriggeredConfigurationGroup(false, true, false, false) 3475 3471 { 3476 3472 setLabel(QObject::tr("Audio System")); 3477 3473 setUseLabel(false); 3478 3474 3479 3475 addChild(AudioOutputDevice()); 3480 addChild(PassThroughOutputDevice());3481 3476 3482 addChild(MaxAudioChannels());3483 addChild( AudioUpmixType());3477 Setting *numchannels = MaxAudioChannels(); 3478 addChild(numchannels); 3484 3479 3485 // General boolean settings 3486 addChild(AC3PassThrough()); 3487 addChild(DTSPassThrough()); 3488 addChild(AggressiveBuffer()); 3480 ConfigurationGroup *dummy = 3481 new VerticalConfigurationGroup(false, true, false, false); 3482 3483 ConfigurationGroup *settings = 3484 new VerticalConfigurationGroup(false, true, false, false); 3485 3486 settings->addChild(AudioUpmix()); 3487 settings->addChild(AudioUpmixType()); 3488 settings->addChild(PassThroughOutputDevice()); 3489 3490 ConfigurationGroup *settings2 = 3491 new HorizontalConfigurationGroup(); 3492 settings2->setLabel(QObject::tr("Audio Processing Capabilities")); 3493 settings2->addChild(AC3PassThrough()); 3494 settings2->addChild(DTSPassThrough()); 3495 3496 settings->addChild(settings2); 3497 3498 // Show surround/upmixer config only if 5.1 Audio is selected 3499 setTrigger(numchannels); 3500 addTarget("2", dummy); 3501 addTarget("6", settings); 3502 3489 3503 } 3490 3504 }; 3491 3505 -
mythtv/programs/mythtranscode/transcode.cpp
37 37 AudioReencodeBuffer(int audio_bits, int audio_channels) 38 38 { 39 39 Reset(); 40 const AudioSettings settings(audio_bits, audio_channels, 0, false);40 const AudioSettings settings(audio_bits, audio_channels, 0, 0, false); 41 41 Reconfigure(settings); 42 42 bufsize = 512000; 43 43 audiobuffer = new unsigned char[bufsize]; … … 210 210 // Do nothing 211 211 return kMuteOff; 212 212 } 213 virtual bool ToggleUpmix(void) 214 { 215 // Do nothing 216 return false; 217 } 213 218 219 virtual void SetSWVolume(int new_volume, bool save) 220 { 221 // Do nothing 222 return; 223 } 224 virtual int GetSWVolume(void) 225 { 226 // Do nothing 227 return 100; 228 } 229 214 230 // These are pure virtual in AudioOutput, but we don't need them here 215 231 virtual void bufferOutputData(bool){ return; } 216 232 virtual int readOutputData(unsigned char*, int ){ return 0; }