Ticket #5900: ticket5900@trunk19685.diff
File ticket5900@trunk19685.diff, 79.9 KB (added by , 17 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; … … 1196 1198 } 1197 1199 } 1198 1200 1201 void PlaybackBoxMusic::toggleUpmix() 1202 { 1203 if (gPlayer->getOutput()) 1204 gPlayer->getOutput()->ToggleUpmix(); 1205 } 1206 1207 1199 1208 void PlaybackBoxMusic::showProgressBar() 1200 1209 { 1201 1210 if (progress_bar && visualizer_status != 2) -
mythplugins/mythmusic/mythmusic/main.cpp
368 368 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 369 369 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 370 370 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 371 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 371 372 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 372 373 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 373 374 REG_KEY("Music", "THMBUP", "Increase rating", "9"); -
mythplugins/mythmusic/mythmusic/musicplayer.cpp
354 354 355 355 void MusicPlayer::openOutputDevice(void) 356 356 { 357 QString adevice ;357 QString adevice, pdevice; 358 358 359 359 if (gContext->GetSetting("MusicAudioDevice") == "default") 360 360 adevice = gContext->GetSetting("AudioOutputDevice"); 361 361 else 362 362 adevice = gContext->GetSetting("MusicAudioDevice"); 363 363 364 pdevice = gContext->GetSetting("PassThruOutputDevice"); 365 364 366 // TODO: Error checking that device is opened correctly! 365 m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,367 m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100, 366 368 AUDIOOUTPUT_MUSIC, true, false); 367 369 m_output->setBufferSize(256 * 1024); 368 370 m_output->SetBlocking(false); -
mythplugins/mythmusic/mythmusic/playbackbox.h
70 70 void changeVolume(bool up_or_down); 71 71 void changeSpeed(bool up_or_down); 72 72 void toggleMute(); 73 void toggleUpmix(); 73 74 void resetTimer(); 74 75 void hideVolume(){showVolume(false);} 75 76 void showVolume(bool on_or_off); -
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
213 213 audio_passthru_device(QString::null), 214 214 audio_channels(2), audio_bits(-1), 215 215 audio_samplerate(44100), audio_stretchfactor(1.0f), 216 audio_codec(NULL),217 216 // Picture-in-Picture stuff 218 217 pip_active(false), pip_visible(true), 219 218 // Preview window support … … 902 901 if (audioOutput) 903 902 { 904 903 const AudioSettings settings( 905 audio_bits, audio_channels, audio_samplerate, 906 audio_passthru, audio_codec); 904 audio_bits, audio_channels, audio_samplerate, audio_passthru); 907 905 audioOutput->Reconfigure(settings); 906 if (audio_passthru) 907 audio_channels = 2; 908 908 errMsg = audioOutput->GetError(); 909 909 if (!errMsg.isEmpty()) 910 910 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3825 3825 audio_passthru = passthru; 3826 3826 } 3827 3827 3828 void NuppelVideoPlayer::SetAudioCodec(void *ac)3829 {3830 audio_codec = ac;3831 }3832 3833 3828 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3834 3829 { 3835 3830 if (audioOutput) … … 5248 5243 } 5249 5244 } 5250 5245 5246 bool NuppelVideoPlayer::ToggleUpmix() 5247 { 5248 if (audioOutput) 5249 return audioOutput->ToggleUpmix(); 5250 return false; 5251 } 5252 5251 5253 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5252 5254 { 5253 5255 if (videoOutput) -
mythtv/libs/libmythtv/avformatdecoder.cpp
427 427 audioSamples(NULL), 428 428 allow_ac3_passthru(false), allow_dts_passthru(false), 429 429 disable_passthru(false), max_channels(2), 430 dummy_frame(NULL),430 last_ac3_channels(0), dummy_frame(NULL), 431 431 // DVD 432 432 lastdvdtitle(-1), 433 433 decodeStillFrame(false), … … 2976 2976 { 2977 2977 int idx = atracks[i].av_stream_index; 2978 2978 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 2979 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&2980 !disable_passthru &&2981 (codec_ctx->codec_id == CODEC_ID_AC3));2982 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&2983 !disable_passthru &&2984 (codec_ctx->codec_id == CODEC_ID_DTS));2985 2979 AudioInfo item(codec_ctx->codec_id, 2986 2980 codec_ctx->sample_rate, codec_ctx->channels, 2987 do_ac3_passthru || do_dts_passthru);2981 DoPassThrough(codec_ctx)); 2988 2982 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2989 2983 } 2990 2984 #endif … … 3118 3112 bool AvFormatDecoder::GetFrame(int onlyvideo) 3119 3113 { 3120 3114 AVPacket *pkt = NULL; 3115 AC3HeaderInfo hdr; 3121 3116 int len; 3122 3117 unsigned char *ptr; 3123 3118 int data_size = 0; … … 3314 3309 pts = 0; 3315 3310 3316 3311 AVStream *curstream = ic->streams[pkt->stream_index]; 3312 AVCodecContext *ctx = curstream->codec; 3317 3313 3318 3314 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3319 3315 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3320 3316 3321 3317 if (ringBuffer->isDVD() && 3322 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3318 ctx->codec_type == CODEC_TYPE_VIDEO) 3323 3319 { 3324 3320 MpegPreProcessPkt(curstream, pkt); 3325 3321 … … 3341 3337 3342 3338 if (!d->HasMPEG2Dec()) 3343 3339 { 3344 int current_width = c urstream->codec->width;3340 int current_width = ctx->width; 3345 3341 int video_width = GetNVP()->GetVideoSize().width(); 3346 3342 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3347 3343 { … … 3382 3378 } 3383 3379 3384 3380 if (storevideoframes && 3385 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3381 ctx->codec_type == CODEC_TYPE_VIDEO) 3386 3382 { 3387 3383 av_dup_packet(pkt); 3388 3384 storedPackets.append(pkt); … … 3390 3386 continue; 3391 3387 } 3392 3388 3393 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3389 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3394 3390 pkt->stream_index == selectedVideoIndex) 3395 3391 { 3396 3392 AVCodecContext *context = curstream->codec; 3397 3393 3398 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3399 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3400 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3401 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||3402 c ontext->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)3394 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3395 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3396 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3397 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD || 3398 ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU) 3403 3399 { 3404 3400 if (!ringBuffer->isDVD()) 3405 3401 MpegPreProcessPkt(curstream, pkt); 3406 3402 } 3407 else if (c ontext->codec_id == CODEC_ID_H264 ||3408 c ontext->codec_id == CODEC_ID_H264_VDPAU)3403 else if (ctx->codec_id == CODEC_ID_H264 || 3404 ctx->codec_id == CODEC_ID_H264_VDPAU) 3409 3405 { 3410 3406 H264PreProcessPkt(curstream, pkt); 3411 3407 } … … 3450 3446 } 3451 3447 3452 3448 if (len > 0 && 3453 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3454 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3449 ctx->codec_type == CODEC_TYPE_DATA && 3450 ctx->codec_id == CODEC_ID_MPEG2VBI) 3455 3451 { 3456 3452 ProcessVBIDataPacket(curstream, pkt); 3457 3453 … … 3460 3456 } 3461 3457 3462 3458 if (len > 0 && 3463 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3464 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3459 ctx->codec_type == CODEC_TYPE_DATA && 3460 ctx->codec_id == CODEC_ID_DVB_VBI) 3465 3461 { 3466 3462 ProcessDVBDataPacket(curstream, pkt); 3467 3463 … … 3471 3467 3472 3468 #ifdef USING_MHEG 3473 3469 if (len > 0 && 3474 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3475 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3470 ctx->codec_type == CODEC_TYPE_DATA && 3471 ctx->codec_id == CODEC_ID_DSMCC_B) 3476 3472 { 3477 3473 ProcessDSMCCPacket(curstream, pkt); 3478 3474 … … 3493 3489 #endif // USING_MHEG 3494 3490 3495 3491 // we don't care about other data streams 3496 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3492 if (ctx->codec_type == CODEC_TYPE_DATA) 3497 3493 { 3498 3494 av_free_packet(pkt); 3499 3495 continue; 3500 3496 } 3501 3497 3502 if (!c urstream->codec->codec)3498 if (!ctx->codec) 3503 3499 { 3504 3500 VERBOSE(VB_PLAYBACK, LOC + 3505 3501 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3506 3502 .arg(pkt->stream_index) 3507 .arg(codec_type_string(c urstream->codec->codec_type))3508 .arg(codec_id_string(c urstream->codec->codec_id))3509 .arg(c urstream->codec->codec_id));3503 .arg(codec_type_string(ctx->codec_type)) 3504 .arg(codec_id_string(ctx->codec_id)) 3505 .arg(ctx->codec_id)); 3510 3506 av_free_packet(pkt); 3511 3507 continue; 3512 3508 } … … 3515 3511 have_err = false; 3516 3512 3517 3513 avcodeclock.lock(); 3518 int ctype = c urstream->codec->codec_type;3514 int ctype = ctx->codec_type; 3519 3515 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3520 3516 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3521 3517 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3540 3536 3541 3537 // detect switches between stereo and dual languages 3542 3538 bool wasDual = audSubIdx != -1; 3543 bool isDual = c urstream->codec->avcodec_dual_language;3539 bool isDual = ctx->avcodec_dual_language; 3544 3540 if ((wasDual && !isDual) || (!wasDual && isDual)) 3545 3541 { 3546 3542 SetupAudioStreamSubIndexes(audIdx); 3547 3543 reselectAudioTrack = true; 3548 3544 } 3549 3545 3550 bool do_ac3_passthru =3551 (allow_ac3_passthru && !transcoding &&3552 (curstream->codec->codec_id == CODEC_ID_AC3));3553 bool do_dts_passthru =3554 (allow_dts_passthru && !transcoding &&3555 (curstream->codec->codec_id == CODEC_ID_DTS));3556 bool using_passthru = do_ac3_passthru || do_dts_passthru;3557 3558 3546 // detect channels on streams that need 3559 3547 // to be decoded before we can know this 3560 3548 bool already_decoded = false; 3561 if (!c urstream->codec->channels)3549 if (!ctx->channels) 3562 3550 { 3563 3551 QMutexLocker locker(&avcodeclock); 3564 3552 VERBOSE(VB_IMPORTANT, LOC + 3565 3553 QString("Setting channels to %1") 3566 3554 .arg(audioOut.channels)); 3567 3555 3568 if ( using_passthru)3556 if (DoPassThrough(ctx)) 3569 3557 { 3570 3558 // for passthru let it select the max number 3571 3559 // of channels 3572 c urstream->codec->channels = 0;3573 c urstream->codec->request_channels = 0;3560 ctx->channels = 0; 3561 ctx->request_channels = 0; 3574 3562 } 3575 3563 else 3576 3564 { 3577 c urstream->codec->channels = audioOut.channels;3578 c urstream->codec->request_channels =3565 ctx->channels = audioOut.channels; 3566 ctx->request_channels = 3579 3567 audioOut.channels; 3580 3568 } 3581 3569 data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 3582 ret = avcodec_decode_audio2(c urstream->codec,3570 ret = avcodec_decode_audio2(ctx, 3583 3571 audioSamples, &data_size, 3584 3572 ptr, len); 3585 3573 already_decoded = true; 3586 3574 3587 reselectAudioTrack |= c urstream->codec->channels;3575 reselectAudioTrack |= ctx->channels; 3588 3576 } 3577 if (ctx->codec_id == CODEC_ID_AC3) 3578 { 3579 GetBitContext gbc; 3580 init_get_bits(&gbc, ptr, len * 8); 3581 if (!ff_ac3_parse_header(&gbc, &hdr)) 3582 { 3583 if (hdr.channels != last_ac3_channels) 3584 { 3585 last_ac3_channels = ctx->channels = hdr.channels; 3586 SetupAudioStream(); 3587 } 3588 } 3589 } 3589 3590 3590 3591 if (reselectAudioTrack) 3591 3592 { … … 3600 3601 .av_stream_index; 3601 3602 audSubIdx = selectedTrack[kTrackTypeAudio] 3602 3603 .av_substream_index; 3604 ctx = curstream->codec; 3603 3605 } 3604 3606 3605 3607 if ((onlyvideo > 0) || (pkt->stream_index != audIdx)) … … 3631 3633 if (audioOut.do_passthru) 3632 3634 { 3633 3635 data_size = pkt->size; 3634 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3636 bool dts = CODEC_ID_DTS == ctx->codec_id; 3635 3637 ret = encode_frame(dts, ptr, len, 3636 3638 audioSamples, data_size); 3637 3639 } 3638 3640 else 3639 3641 { 3640 AVCodecContext *ctx = curstream->codec;3641 3642 3642 if ((ctx->channels == 0) || 3643 3643 (ctx->channels > audioOut.channels)) 3644 3644 { … … 3647 3647 3648 3648 if (!already_decoded) 3649 3649 { 3650 curstream->codec->request_channels = 3651 audioOut.channels; 3650 ctx->request_channels = audioOut.channels; 3652 3651 data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 3653 3652 ret = avcodec_decode_audio2(ctx, audioSamples, 3654 3653 &data_size, ptr, len); … … 3666 3665 audIdx = -1; 3667 3666 AutoSelectAudioTrack(); 3668 3667 data_size = 0; 3668 ctx = curstream->codec; 3669 3669 } 3670 3670 } 3671 3671 avcodeclock.unlock(); … … 3683 3683 3684 3684 // calc for next frame 3685 3685 lastapts += (long long)((double)(data_size * 1000) / 3686 (curstream->codec->channels * 2) / 3687 curstream->codec->sample_rate); 3686 (ctx->channels * 2) / ctx->sample_rate); 3688 3687 3689 3688 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, 3690 3689 LOC + QString("audio timecode %1 %2 %3 %4") … … 3752 3751 continue; 3753 3752 } 3754 3753 3755 AVCodecContext *context = curstream->codec;3756 3754 AVFrame mpa_pic; 3757 3755 bzero(&mpa_pic, sizeof(AVFrame)); 3758 3756 … … 3767 3765 // HACK 3768 3766 while (!gotpicture && count < 5) 3769 3767 { 3770 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3768 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3771 3769 &gotpicture, ptr, len); 3772 3770 count++; 3773 3771 } 3774 3772 } 3775 3773 else 3776 3774 { 3777 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3775 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3778 3776 &gotpicture, ptr, len); 3779 3777 } 3780 3778 } 3781 3779 else 3782 3780 { 3783 ret = avcodec_decode_video(c ontext, &mpa_pic,3781 ret = avcodec_decode_video(ctx, &mpa_pic, 3784 3782 &gotpicture, ptr, len); 3785 3783 // Reparse it to not drop the DVD still frame 3786 3784 if (decodeStillFrame) 3787 ret = avcodec_decode_video(c ontext, &mpa_pic,3785 ret = avcodec_decode_video(ctx, &mpa_pic, 3788 3786 &gotpicture, ptr, len); 3789 3787 } 3790 3788 avcodeclock.unlock(); … … 3851 3849 3852 3850 img_convert(&tmppicture, PIX_FMT_YUV420P, 3853 3851 (AVPicture *)&mpa_pic, 3854 c ontext->pix_fmt,3855 c ontext->width,3856 c ontext->height);3852 ctx->pix_fmt, 3853 ctx->width, 3854 ctx->height); 3857 3855 3858 3856 if (xf) 3859 3857 { … … 3876 3874 (temppts + 10000 > lastvpts || temppts < 0)) 3877 3875 { 3878 3876 temppts = lastvpts; 3879 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3877 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3880 3878 // MPEG2 frames can be repeated, update pts accordingly 3881 3879 temppts += (long long)(mpa_pic.repeat_pict * 500 3882 * av_q2d(c urstream->codec->time_base));3880 * av_q2d(ctx->time_base)); 3883 3881 } 3884 3882 3885 3883 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + … … 3915 3913 picframe->frameNumber = framesPlayed; 3916 3914 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3917 3915 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3918 c ontext->release_buffer(context, &mpa_pic);3916 ctx->release_buffer(ctx, &mpa_pic); 3919 3917 3920 3918 decoded_video_frame = picframe; 3921 3919 gotvideo = 1; … … 3971 3969 } 3972 3970 default: 3973 3971 { 3974 AVCodecContext *enc = curstream->codec;3975 3972 VERBOSE(VB_IMPORTANT, LOC_ERR + 3976 3973 QString("Decoding - id(%1) type(%2)") 3977 .arg(codec_id_string( enc->codec_id))3978 .arg(codec_type_string( enc->codec_type)));3974 .arg(codec_id_string(ctx->codec_id)) 3975 .arg(codec_type_string(ctx->codec_type))); 3979 3976 have_err = true; 3980 3977 break; 3981 3978 } … … 4124 4121 } 4125 4122 } 4126 4123 4124 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 4125 { 4126 bool passthru = false; 4127 4128 if (ctx->codec_id == CODEC_ID_AC3) 4129 passthru = allow_ac3_passthru && 4130 ctx->channels >= (int)max_channels; 4131 else if (ctx->codec_id == CODEC_ID_DTS) 4132 passthru = allow_dts_passthru; 4133 4134 passthru &= !transcoding && !disable_passthru; 4135 // Don't know any cards that support spdif clocked at < 44100 4136 // Some US cable transmissions have 2ch 32k AC-3 streams 4137 passthru &= ctx->sample_rate >= 44100; 4138 4139 return passthru; 4140 } 4141 4127 4142 /** \fn AvFormatDecoder::SetupAudioStream(void) 4128 4143 * \brief Reinitializes audio if it needs to be reinitialized. 4129 4144 * … … 4137 4152 AVStream *curstream = NULL; 4138 4153 AVCodecContext *codec_ctx = NULL; 4139 4154 AudioInfo old_in = audioIn; 4140 AudioInfo old_out = audioOut;4141 4155 bool using_passthru = false; 4142 4156 4143 4157 if ((currentTrack[kTrackTypeAudio] >= 0) && … … 4151 4165 codec_ctx = curstream->codec; 4152 4166 if (codec_ctx) 4153 4167 { 4154 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4155 (codec_ctx->codec_id == CODEC_ID_AC3)); 4156 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4157 (codec_ctx->codec_id == CODEC_ID_DTS)); 4158 using_passthru = do_ac3_passthru || do_dts_passthru; 4159 info = AudioInfo(codec_ctx->codec_id, 4160 codec_ctx->sample_rate, codec_ctx->channels, 4161 using_passthru && !disable_passthru); 4168 using_passthru = DoPassThrough(codec_ctx); 4169 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4170 codec_ctx->channels, using_passthru); 4162 4171 } 4163 4172 } 4164 4173 … … 4175 4184 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4176 4185 4177 4186 audioOut = audioIn = info; 4178 AudioInfo tmpAudioOut = audioOut;4179 4187 4180 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4181 if (using_passthru && !disable_passthru) 4188 if (!using_passthru && audioOut.channels > (int)max_channels) 4182 4189 { 4183 tmpAudioOut.channels = 2; 4184 tmpAudioOut.sample_rate = 48000; 4185 tmpAudioOut.sample_size = 4; 4186 } 4187 4188 if (audioOut.channels > (int) max_channels) 4189 { 4190 audioOut.channels = (int) max_channels; 4190 audioOut.channels = (int)max_channels; 4191 4191 audioOut.sample_size = audioOut.channels * 2; 4192 codec_ctx->channels 4192 codec_ctx->channels = audioOut.channels; 4193 4193 } 4194 4194 4195 if (!using_passthru)4196 tmpAudioOut = audioOut;4197 4198 4195 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4199 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4200 .arg((using_passthru) ? "digital passthrough " : "") 4201 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4202 .arg(old_in.toString()).arg(old_out.toString()) 4203 .arg(audioIn.toString()).arg(audioOut.toString())); 4196 QString("\n\t\t\tfrom %1 to %2") 4197 .arg(old_in.toString()).arg(audioOut.toString())); 4204 4198 4205 if ( tmpAudioOut.sample_rate > 0)4206 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4199 if (audioOut.sample_rate > 0) 4200 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4207 4201 4208 GetNVP()->SetAudioParams( tmpAudioOut.bps(), tmpAudioOut.channels,4209 tmpAudioOut.sample_rate, audioIn.do_passthru);4202 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4203 audioOut.sample_rate, audioOut.do_passthru); 4210 4204 4211 // allow the audio stuff to reencode4212 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4213 4205 GetNVP()->ReinitAudio(); 4214 4206 4215 4207 return true; -
mythtv/libs/libmythtv/tv_play.h
406 406 void NormalSpeed(PlayerContext*); 407 407 void ChangeSpeed(PlayerContext*, int direction); 408 408 void ToggleTimeStretch(PlayerContext*); 409 void ToggleUpmix(PlayerContext*); 409 410 void ChangeTimeStretch(PlayerContext*, int dir, bool allowEdit = true); 410 411 bool TimeStretchHandleAction(PlayerContext*, 411 412 const QStringList &actions); -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
180 180 // Toggle Sets 181 181 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 182 182 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 183 bool ToggleUpmix(void); 183 184 184 185 // Gets 185 186 QSize GetVideoBufferSize(void) const { return video_dim; } … … 706 707 int audio_bits; 707 708 int audio_samplerate; 708 709 float audio_stretchfactor; 709 void *audio_codec;710 710 bool audio_passthru; 711 711 712 712 // Picture-in-Picture -
mythtv/libs/libmythtv/tv_play.cpp
428 428 REG_KEY("TV Frontend", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 429 429 REG_KEY("TV Frontend", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 430 430 REG_KEY("TV Frontend", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 431 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 431 432 REG_KEY("TV Frontend", "RANKINC", "Increase program or channel rank", 432 433 "Right"); 433 434 REG_KEY("TV Frontend", "RANKDEC", "Decrease program or channel rank", … … 613 614 Teletext F2,F3,F4,F5,F6,F7,F8 614 615 ITV F2,F3,F4,F5,F6,F7,F12 615 616 616 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 617 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 617 618 */ 618 619 } 619 620 … … 4216 4217 DoTogglePictureAttribute(ctx, kAdjustingPicture_Playback); 4217 4218 else if (has_action("TOGGLESTRETCH", actions)) 4218 4219 ToggleTimeStretch(ctx); 4220 else if (has_action("TOGGLEUPMIX", actions)) 4221 ToggleUpmix(ctx); 4219 4222 else if (has_action("TOGGLESLEEP", actions)) 4220 4223 ToggleSleepTimer(ctx); 4221 4224 else if (has_action("TOGGLERECORD", actions) && islivetv) … … 7709 7712 ChangeTimeStretch(ctx, 0, false); 7710 7713 } 7711 7714 7715 void TV::ToggleUpmix(PlayerContext *ctx) 7716 { 7717 if (!ctx->nvp || !ctx->nvp->HasAudioOut()) 7718 return; 7719 QString text; 7720 if (ctx->nvp->ToggleUpmix()) 7721 text = tr("Upmixer On"); 7722 else 7723 text = tr("Upmixer Off"); 7724 7725 if (ctx->nvp->GetOSD() && !browsemode) 7726 ctx->nvp->GetOSD()->SetSettingsText(text, 5); 7727 } 7728 7712 7729 void TV::ChangeTimeStretch(PlayerContext *ctx, int dir, bool allowEdit) 7713 7730 { 7714 7731 const float kTimeStretchMin = 0.5; … … 9319 9336 SetManualZoom(actx, true, tr("Zoom Mode ON")); 9320 9337 else if (action == "TOGGLESTRETCH") 9321 9338 ToggleTimeStretch(actx); 9339 else if (action == "TOGGLEUPMIX") 9340 ToggleUpmix(actx); 9322 9341 else if (action.left(13) == "ADJUSTSTRETCH") 9323 9342 { 9324 9343 bool floatRead; … … 9562 9581 FillMenuPlaying(ctx, treeMenu); 9563 9582 9564 9583 FillMenuTracks(ctx, treeMenu, kTrackTypeAudio); 9584 new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 9565 9585 FillMenuTracks(ctx, treeMenu, kTrackTypeSubtitle); 9566 9586 FillMenuTracks(ctx, treeMenu, kTrackTypeCC708); 9567 9587 -
mythtv/libs/libmythtv/avformatdecoder.h
199 199 200 200 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 201 201 202 bool DoPassThrough(const AVCodecContext *ctx); 202 203 bool SetupAudioStream(void); 203 204 void SetupAudioStreamSubIndexes(int streamIndex); 204 205 void RemoveAudioStreams(); … … 270 271 bool allow_dts_passthru; 271 272 bool disable_passthru; 272 273 uint max_channels; 274 uint last_ac3_channels; 273 275 274 276 VideoFrame *dummy_frame; 275 277 -
mythtv/libs/libmythsamplerate/samplerate.c
452 452 { len -- ; 453 453 454 454 scaled_value = in [len] * (8.0 * 0x10000000) ; 455 if ( CPU_CLIPS_POSITIVE == 0 &&scaled_value >= (1.0 * 0x7FFFFFFF))455 if (scaled_value >= (1.0 * 0x7FFFFFFF)) 456 456 { out [len] = 32767 ; 457 457 continue ; 458 458 } ; 459 if ( CPU_CLIPS_NEGATIVE == 0 &&scaled_value <= (-8.0 * 0x10000000))459 if (scaled_value <= (-8.0 * 0x10000000)) 460 460 { out [len] = -32768 ; 461 461 continue ; 462 462 } ; -
mythtv/libs/libmyth/audiosettings.cpp
15 15 samplerate(-1), 16 16 set_initial_vol(false), 17 17 use_passthru(false), 18 codec(NULL),19 18 source(AUDIOOUTPUT_UNKNOWN) 20 19 { 21 20 } … … 28 27 samplerate(other.samplerate), 29 28 set_initial_vol(other.set_initial_vol), 30 29 use_passthru(other.use_passthru), 31 codec(other.codec),32 30 source(other.source) 33 31 { 34 32 } … … 41 39 int audio_samplerate, 42 40 AudioOutputSource audio_source, 43 41 bool audio_set_initial_vol, 44 bool audio_use_passthru, 45 void *audio_codec) : 42 bool audio_use_passthru) : 46 43 main_device(audio_main_device), 47 44 passthru_device(audio_passthru_device), 48 45 bits(audio_bits), … … 50 47 samplerate(audio_samplerate), 51 48 set_initial_vol(audio_set_initial_vol), 52 49 use_passthru(audio_use_passthru), 53 codec(audio_codec),54 50 source(audio_source) 55 51 { 56 52 } … … 59 55 int audio_bits, 60 56 int audio_channels, 61 57 int audio_samplerate, 62 bool audio_use_passthru, 63 void *audio_codec) : 58 bool audio_use_passthru) : 64 59 main_device(QString::null), 65 60 passthru_device(QString::null), 66 61 bits(audio_bits), … … 68 63 samplerate(audio_samplerate), 69 64 set_initial_vol(false), 70 65 use_passthru(audio_use_passthru), 71 codec(audio_codec),72 66 source(AUDIOOUTPUT_UNKNOWN) 73 67 { 74 68 } -
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 … … 132 133 QString audio_passthru_device; 133 134 134 135 bool audio_passthru; 136 bool audio_enc; 137 bool audio_reenc; 135 138 136 139 float audio_stretchfactor; 137 AVCodecContext *audio_codec;138 140 AudioOutputSource source; 139 141 140 142 bool killaudio; … … 144 146 bool buffer_output_data_for_use; // used by AudioOutputNULL 145 147 146 148 int configured_audio_channels; 149 int orig_config_channels; 150 int src_quality; 147 151 148 152 private: 149 153 // resampler … … 156 160 FreeSurround *upmixer; 157 161 158 162 int source_audio_channels; 163 int source_audio_samplerate; 159 164 int source_audio_bytes_per_sample; 160 165 bool needs_upmix; 161 166 int surround_mode; 167 bool allow_ac3_passthru; 168 float old_audio_stretchfactor; 162 169 163 170 bool blocking; // do AddSamples calls block? 164 171 -
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 snd_ctl_open(&ctl, "default", 0); 53 snd_ctl_elem_list_alloca(&clist); 54 snd_ctl_elem_list(ctl, clist); 55 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 56 snd_ctl_elem_list(ctl, clist); 57 controls = snd_ctl_elem_list_get_used(clist); 58 for (cidx = 0; cidx < controls; cidx++) { 59 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 60 if (spdif_index < 0 || 61 snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index) 62 break; 63 } 64 65 if (cidx >= controls) 66 return; 67 68 snd_ctl_elem_id_alloca(&cid); 69 snd_ctl_elem_list_get_id(clist, cidx, cid); 70 snd_ctl_elem_value_alloca(&cval); 71 snd_ctl_elem_value_set_id(cval, cid); 72 snd_ctl_elem_read(ctl,cval); 73 snd_ctl_elem_value_get_iec958(cval, &iec958); 74 75 if (!audio) 76 iec958.status[0] |= IEC958_AES0_NONAUDIO; 77 else 78 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 79 80 snd_ctl_elem_value_set_iec958(cval, &iec958); 81 snd_ctl_elem_write(ctl, cval); 82 83 } 84 37 85 bool AudioOutputALSA::OpenDevice() 38 86 { 39 87 snd_pcm_format_t format; 40 88 unsigned int buffer_time, period_time; 41 89 int err; 90 QString real_device; 42 91 43 92 if (pcm_handle != NULL) 44 93 CloseDevice(); 45 94 46 95 pcm_handle = NULL; 47 96 numbadioctls = 0; 97 98 if (audio_passthru || audio_enc) 99 { 100 real_device = audio_passthru_device; 101 SetIECStatus(false); 102 } 103 else 104 { 105 real_device = audio_main_device; 106 SetIECStatus(true); 107 } 48 108 49 QString real_device = (audio_passthru) ?50 audio_passthru_device : audio_main_device;51 52 109 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 110 .arg(real_device)); 54 111 -
mythtv/libs/libmyth/audiooutputbase.cpp
28 28 29 29 audio_main_device(settings.GetMainDevice()), 30 30 audio_passthru_device(settings.GetPassthruDevice()), 31 audio_passthru(false), audio_stretchfactor(1.0f), 31 audio_passthru(false), audio_enc(false), 32 audio_reenc(false), audio_stretchfactor(1.0f), 32 33 33 audio_codec(NULL),34 34 source(settings.source), killaudio(false), 35 35 36 36 pauseaudio(false), audio_actually_paused(false), … … 48 48 encoder(NULL), 49 49 upmixer(NULL), 50 50 source_audio_channels(-1), 51 source_audio_samplerate(0), 51 52 source_audio_bytes_per_sample(0), 52 53 needs_upmix(false), 53 54 surround_mode(FreeSurround::SurroundModePassive), 55 old_audio_stretchfactor(1.0), 54 56 55 57 blocking(false), 56 58 … … 79 81 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 80 82 memset(audiobuffer, 0, sizeof(char) * kAudioRingBufferSize); 81 83 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 84 orig_config_channels = configured_audio_channels; 85 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 86 src_quality = gContext->GetNumSetting("SRCQuality", 3); 82 87 83 88 // You need to call Reconfigure from your concrete class. 84 89 // Reconfigure(laudio_bits, laudio_channels, … … 124 129 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 130 .arg(audio_stretchfactor)); 126 131 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)); 132 pSoundStretch->setSampleRate(audio_samplerate); 133 pSoundStretch->setChannels(upmixer ? 134 configured_audio_channels : source_audio_channels); 135 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->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 136 pSoundStretch->setTempo(audio_stretchfactor); 163 137 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 164 138 165 139 // dont need these with only tempo change 166 140 //pSoundStretch->setPitch(1.0); 167 141 //pSoundStretch->setRate(1.0); 168 169 142 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 143 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 144 } … … 183 156 return audio_stretchfactor; 184 157 } 185 158 159 bool AudioOutputBase::ToggleUpmix(void) 160 { 161 if (orig_config_channels == 2 || audio_passthru) 162 return false; 163 if (configured_audio_channels == 6) 164 configured_audio_channels = 2; 165 else 166 configured_audio_channels = 6; 167 168 const AudioSettings settings(audio_bits, source_audio_channels, 169 source_audio_samplerate, audio_passthru); 170 Reconfigure(settings); 171 return (configured_audio_channels == 6); 172 } 173 174 186 175 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 176 { 188 177 AudioSettings settings = orig_settings; 189 178 190 int codec_id = CODEC_ID_NONE;191 int lcodec_id = CODEC_ID_NONE;192 int lcchannels = 0;193 int cchannels = 0;194 179 int lsource_audio_channels = settings.channels; 195 180 bool lneeds_upmix = false; 181 bool laudio_reenc = false; 196 182 197 if (settings.codec) 198 { 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; 205 } 183 // Are we reencoding a (previously) timestretched bitstream? 184 if (settings.channels > 2 && !settings.use_passthru) 185 laudio_reenc = true; 206 186 207 if (audio_codec) 187 // Enough channels? Upmix if not 188 if (settings.channels < configured_audio_channels && 189 !settings.use_passthru) 208 190 { 209 codec_id = audio_codec->codec_id;210 cchannels = ((AVCodecContext*)audio_codec)->channels;211 }212 213 if ((configured_audio_channels == 6) &&214 !(settings.codec || audio_codec))215 {216 191 settings.channels = configured_audio_channels; 217 192 lneeds_upmix = true; 218 193 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); … … 224 199 settings.samplerate == audio_samplerate && !need_resampler && 225 200 settings.use_passthru == audio_passthru && 226 201 lneeds_upmix == needs_upmix && 227 l codec_id == codec_id && lcchannels == cchannels);202 laudio_reenc == audio_reenc); 228 203 bool upmix_deps = 229 204 (lsource_audio_channels == source_audio_channels); 230 205 if (general_deps && upmix_deps) … … 251 226 waud = raud = 0; 252 227 audio_actually_paused = false; 253 228 254 bool redo_stretch = (pSoundStretch && audio_channels != settings.channels);255 229 audio_channels = settings.channels; 256 230 source_audio_channels = lsource_audio_channels; 257 231 audio_bits = settings.bits; 258 audio_samplerate = settings.samplerate;259 audio_ codec = (AVCodecContext*)settings.codec;232 source_audio_samplerate = audio_samplerate = settings.samplerate; 233 audio_reenc = laudio_reenc; 260 234 audio_passthru = settings.use_passthru; 261 235 needs_upmix = lneeds_upmix; 262 236 … … 265 239 Error("AudioOutput only supports 8 or 16bit audio."); 266 240 return; 267 241 } 268 audio_bytes_per_sample = audio_channels * audio_bits / 8;269 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;270 242 271 243 need_resampler = false; 272 244 killaudio = false; … … 275 247 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 276 248 277 249 numlowbuffer = 0; 250 251 // Encode to AC-3 if not passing thru , there's > 2 channels 252 // and a passthru device is defined 253 if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 254 { 255 int srate = src_quality == 0 ? audio_samplerate : 48000; 256 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 257 encoder = new AudioOutputDigitalEncoder(); 258 if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 259 configured_audio_channels, audio_reenc)) 260 { 261 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 262 delete encoder; 263 encoder = NULL; 264 } 265 266 audio_enc = true; 267 } 268 269 if(audio_passthru || audio_enc) 270 // AC-3 output - soundcard expects a 2ch 48k stream 271 audio_channels = 2; 272 273 audio_bytes_per_sample = audio_channels * audio_bits / 8; 274 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 278 275 276 // Always resample to 48k - many cards can't do anything else 277 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 278 if (src_quality != 0 && audio_samplerate != 48000) 279 { 280 int error; 281 audio_samplerate = 48000; 282 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 283 .arg(settings.samplerate).arg(audio_samplerate)); 284 src_ctx = src_new(3-src_quality, audio_channels, &error); 285 if (error) 286 { 287 Error(QString("Error creating resampler, the error was: %1") 288 .arg(src_strerror(error)) ); 289 src_ctx = NULL; 290 return; 291 } 292 src_data.src_ratio = (double) audio_samplerate / settings.samplerate; 293 src_data.data_in = src_in; 294 src_data.data_out = src_out; 295 src_data.output_frames = 16384*6; 296 need_resampler = true; 297 } 298 279 299 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 280 300 .arg(audio_main_device).arg(audio_channels) 281 301 .arg(source_audio_channels).arg(audio_samplerate)); … … 309 329 current_seconds = -1; 310 330 source_bitrate = -1; 311 331 312 // NOTE: this won't do anything as above samplerate vars are set equal313 // Check if we need the resampler314 if (audio_samplerate != settings.samplerate)315 {316 int error;317 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")318 .arg(settings.samplerate).arg(audio_samplerate));319 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);320 if (error)321 {322 Error(QString("Error creating resampler, the error was: %1")323 .arg(src_strerror(error)) );324 return;325 }326 src_data.src_ratio = (double) audio_samplerate / settings.samplerate;327 src_data.data_in = src_in;328 src_data.data_out = src_out;329 src_data.output_frames = 16384*6;330 need_resampler = true;331 }332 333 332 if (needs_upmix) 334 333 { 335 334 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 344 343 (FreeSurround::SurroundMode)surround_mode); 345 344 346 345 VERBOSE(VB_AUDIO, LOC + 347 QString(" create upmixer done with surround mode %1")346 QString("Create upmixer done with surround mode %1") 348 347 .arg(surround_mode)); 349 348 } 350 349 351 350 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 352 351 .arg(audio_stretchfactor)); 353 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")354 .arg((audio_codec) ?355 codec_id_string(audio_codec->codec_id) : "not set"));356 352 357 if (redo_stretch) 358 { 359 delete pSoundStretch; 360 pSoundStretch = NULL; 361 SetStretchFactorLocked(audio_stretchfactor); 362 } 363 else 364 { 365 SetStretchFactorLocked(audio_stretchfactor); 366 if (pSoundStretch) 367 { 368 // if its passthru then we need to reencode 369 if (audio_codec) 370 { 371 if (!encoder) 372 { 373 VERBOSE(VB_AUDIO, LOC + 374 QString("Creating Encoder for codec %1") 375 .arg(audio_codec->codec_id)); 376 377 encoder = new AudioOutputDigitalEncoder(); 378 if (!encoder->Init(audio_codec->codec_id, 379 audio_codec->bit_rate, 380 audio_codec->sample_rate, 381 audio_codec->channels 382 )) 383 { 384 // eeks 385 delete encoder; 386 encoder = NULL; 387 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 388 } 389 } 390 } 391 if (audio_codec && encoder) 392 { 393 pSoundStretch->setSampleRate(audio_codec->sample_rate); 394 pSoundStretch->setChannels(audio_codec->channels); 395 } 396 else 397 { 398 pSoundStretch->setSampleRate(audio_samplerate); 399 pSoundStretch->setChannels(audio_channels); 400 } 401 } 402 } 403 353 SetStretchFactorLocked(old_audio_stretchfactor); 354 404 355 // Setup visualisations, zero the visualisations buffers 405 356 prepareVisuals(); 406 357 … … 436 387 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 437 388 killaudio = true; 438 389 StopOutputThread(); 390 QMutexLocker lock1(&audio_buflock); 439 391 440 392 // Close resampler? 441 393 if (src_ctx) 394 { 442 395 src_delete(src_ctx); 396 src_ctx = NULL; 397 } 398 443 399 need_resampler = false; 444 400 445 401 // close sound stretcher … … 447 403 { 448 404 delete pSoundStretch; 449 405 pSoundStretch = NULL; 406 old_audio_stretchfactor = audio_stretchfactor; 407 audio_stretchfactor = 1.0; 450 408 } 451 409 452 410 if (encoder) … … 461 419 upmixer = NULL; 462 420 } 463 421 needs_upmix = false; 422 audio_enc = false; 464 423 465 424 CloseDevice(); 466 425 … … 562 521 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 563 522 ret = (long long)(ret * audio_stretchfactor); 564 523 565 #if 1566 524 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 567 525 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 568 526 .arg(now.tv_sec).arg(now.tv_usec) … … 571 529 .arg(audiotime) 572 530 .arg(audio_stretchfactor) 573 531 ); 574 #endif575 532 576 533 ret += audiotime; 577 534 … … 611 568 612 569 // include algorithmic latencies 613 570 if (pSoundStretch) 614 {615 // add the effect of any unused but processed samples,616 // AC3 reencode does this617 totalbuffer += (int)(pSoundStretch->numSamples() *618 audio_bytes_per_sample);619 // add the effect of unprocessed samples in time stretch algo620 571 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 621 572 audio_bytes_per_sample) / audio_stretchfactor); 622 }623 573 624 574 if (upmixer && needs_upmix) 625 {626 575 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 627 }628 576 577 if (encoder) 578 totalbuffer += encoder->Buffered(); 579 629 580 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 630 581 (audio_bytes_per_sample * effdspstretched)); 631 582 632 583 gettimeofday(&audiotime_updated, NULL); 633 #if 1 584 634 585 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 635 586 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 636 587 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") … … 642 593 .arg(effdspstretched) 643 594 .arg(audio_bytes_per_sample) 644 595 .arg(audio_stretchfactor)); 645 #endif646 596 } 647 597 648 598 int AudioOutputBase::GetAudioBufferedTime(void) … … 681 631 return false; // would overflow 682 632 } 683 633 634 QMutexLocker lock1(&audio_buflock); 635 684 636 // resample input if necessary 685 637 if (need_resampler && src_ctx) 686 638 { … … 725 677 int abps = (encoder) ? 726 678 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 727 679 int len = samples * abps; 680 681 // Give original samples to mythmusic visualisation 682 dispatchVisual((unsigned char *)buffer, len, timecode, 683 source_audio_channels, audio_bits); 728 684 729 685 // Check we have enough space to write the data 730 686 if (need_resampler && src_ctx) … … 749 705 return false; // would overflow 750 706 } 751 707 708 QMutexLocker lock1(&audio_buflock); 709 752 710 // resample input if necessary 753 711 if (need_resampler && src_ctx) 754 712 { … … 808 766 if (src_ctx) 809 767 { 810 768 int error = src_reset(src_ctx); 811 if (error) 769 if (error) 770 { 812 771 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 813 772 "Error occured while resetting resampler: %1") 814 773 .arg(src_strerror(error))); 774 src_ctx = NULL; 775 } 815 776 } 816 777 } 817 778 } … … 821 782 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 822 783 long long timecode) 823 784 { 824 audio_buflock.lock();825 826 785 int len; // = samples * audio_bytes_per_sample; 827 786 int audio_bytes = audio_bits / 8; 828 787 int org_waud = waud; … … 839 798 .arg(samples * abps) 840 799 .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode) 841 800 .arg(needs_upmix)); 842 801 802 len = WaitForFreeSpace(samples); 803 843 804 if (upmixer && needs_upmix) 844 805 { 845 806 int out_samples = 0; 807 org_waud = waud; 846 808 int step = (interleaved)?source_audio_channels:1; 847 len = WaitForFreeSpace(samples); // test 809 848 810 for (int itemp = 0; itemp < samples; ) 849 811 { 850 // just in case it does a processing cycle, release the lock851 // to allow the output loop to do output852 audio_buflock.unlock();853 812 if (audio_bytes == 2) 854 813 { 855 814 itemp += upmixer->putSamples( … … 866 825 source_audio_channels, 867 826 (interleaved) ? 0 : samples); 868 827 } 869 audio_buflock.lock();870 828 871 829 int copy_samples = upmixer->numSamples(); 872 830 if (copy_samples) … … 900 858 } 901 859 else 902 860 { 903 len = WaitForFreeSpace(samples);904 905 861 if (interleaved) 906 862 { 907 863 char *mybuf = (char*)buffer; … … 936 892 } 937 893 } 938 894 939 if (samples > 0) 895 if (samples <= 0) 896 return; 897 898 if (pSoundStretch) 940 899 { 941 if (pSoundStretch) 900 // does not change the timecode, only the number of samples 901 // back to orig pos 902 org_waud = waud; 903 int bdiff = kAudioRingBufferSize - org_waud; 904 int nSamplesToEnd = bdiff/abps; 905 if (bdiff < len) 942 906 { 907 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 908 (audiobuffer + 909 org_waud), nSamplesToEnd); 910 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 911 (len - bdiff) / abps); 912 } 913 else 914 { 915 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 916 (audiobuffer + org_waud), 917 len / abps); 918 } 943 919 944 // does not change the timecode, only the number of samples 945 // back to orig pos 946 org_waud = waud; 947 int bdiff = kAudioRingBufferSize - org_waud; 948 int nSamplesToEnd = bdiff/abps; 949 if (bdiff < len) 950 { 951 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 952 (audiobuffer + 953 org_waud), nSamplesToEnd); 954 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 955 (len - bdiff) / abps); 920 int nSamples = pSoundStretch->numSamples(); 921 len = WaitForFreeSpace(nSamples); 922 923 while ((nSamples = pSoundStretch->numSamples())) 924 { 925 if (nSamples > nSamplesToEnd) 926 nSamples = nSamplesToEnd; 927 928 nSamples = pSoundStretch->receiveSamples( 929 (soundtouch::SAMPLETYPE*) 930 (audiobuffer + org_waud), nSamples 931 ); 932 933 if (nSamples == nSamplesToEnd) { 934 org_waud = 0; 935 nSamplesToEnd = kAudioRingBufferSize/abps; 956 936 } 957 else 958 { 959 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 960 (audiobuffer + org_waud), 961 len / abps); 937 else { 938 org_waud += nSamples * abps; 939 nSamplesToEnd -= nSamples; 962 940 } 941 942 } 943 944 } 963 945 964 if (encoder)965 {966 // pull out a packet's worth and reencode it until we967 // don't have enough for any more packets968 soundtouch::SAMPLETYPE *temp_buff =969 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();970 size_t frameSize = encoder->FrameSize()/abps;946 // Encode to AC-3? 947 if (encoder) 948 { 949 950 org_waud = waud; 951 int bdiff = kAudioRingBufferSize - org_waud; 952 int to_get = 0; 971 953 972 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 973 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 974 .arg(frameSize) 975 .arg(encoder->FrameSize()) 976 .arg(pSoundStretch->numSamples())); 977 978 // process the same number of samples as it creates 979 // a full encoded buffer just like before 980 while (pSoundStretch->numSamples() >= frameSize) 981 { 982 int got = pSoundStretch->receiveSamples( 983 temp_buff, frameSize); 984 int amount = encoder->Encode(temp_buff); 985 986 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 987 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 988 .arg(amount) 989 .arg(got) 990 .arg(pSoundStretch->numSamples())); 991 992 if (!amount) 993 continue; 994 995 //len = WaitForFreeSpace(amount); 996 char *ob = encoder->GetOutBuff(); 997 if (amount >= bdiff) 998 { 999 memcpy(audiobuffer + org_waud, ob, bdiff); 1000 ob += bdiff; 1001 amount -= bdiff; 1002 org_waud = 0; 1003 } 1004 if (amount > 0) 1005 memcpy(audiobuffer + org_waud, ob, amount); 1006 1007 bdiff = kAudioRingBufferSize - amount; 1008 org_waud = (org_waud + amount) % kAudioRingBufferSize; 1009 } 1010 } 1011 else 954 if (bdiff < len) 955 { 956 encoder->Encode(audiobuffer + org_waud, bdiff); 957 to_get = encoder->Encode(audiobuffer, len - bdiff); 958 } 959 else 960 to_get = encoder->Encode(audiobuffer + org_waud, len); 961 962 if (to_get > 0) 963 { 964 965 if (to_get >= bdiff) 1012 966 { 1013 int newLen = 0; 1014 int nSamples; 1015 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1016 audio_bytes_per_sample); 1017 do 1018 { 1019 int samplesToGet = len/audio_bytes_per_sample; 1020 if (samplesToGet > nSamplesToEnd) 1021 { 1022 samplesToGet = nSamplesToEnd; 1023 } 1024 1025 nSamples = pSoundStretch->receiveSamples( 1026 (soundtouch::SAMPLETYPE*) 1027 (audiobuffer + org_waud), samplesToGet); 1028 if (nSamples == nSamplesToEnd) 1029 { 1030 org_waud = 0; 1031 nSamplesToEnd = kAudioRingBufferSize/audio_bytes_per_sample; 1032 } 1033 else 1034 { 1035 int bufsz = nSamples * audio_bytes_per_sample; 1036 org_waud = (org_waud + bufsz) % kAudioRingBufferSize; 1037 nSamplesToEnd -= nSamples; 1038 } 1039 1040 newLen += nSamples * audio_bytes_per_sample; 1041 len -= nSamples * audio_bytes_per_sample; 1042 } while (nSamples > 0); 967 encoder->GetFrames(audiobuffer + org_waud, bdiff); 968 to_get -= bdiff; 969 org_waud = 0; 1043 970 } 1044 } 971 if (to_get > 0) 972 encoder->GetFrames(audiobuffer + org_waud, to_get); 1045 973 1046 waud = org_waud; 1047 lastaudiolen = audiolen(false); 974 org_waud += to_get; 1048 975 1049 if (timecode < 0)1050 {1051 // mythmusic doesn't give timestamps..1052 timecode = (int)((samples_buffered * 100000.0) / effdsp);1053 976 } 1054 1055 samples_buffered += samples;1056 1057 /* we want the time at the end -- but the file format stores1058 time at the start of the chunk. */1059 // even with timestretch, timecode is still calculated from original1060 // sample count1061 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);1062 977 1063 if (interleaved)1064 {1065 dispatchVisual((unsigned char *)buffer, len, timecode,1066 source_audio_channels, audio_bits);1067 }1068 978 } 1069 979 1070 audio_buflock.unlock(); 980 waud = org_waud; 981 lastaudiolen = audiolen(false); 982 983 if (timecode < 0) 984 // mythmusic doesn't give timestamps.. 985 timecode = (int)((samples_buffered * 100000.0) / effdsp); 986 987 samples_buffered += samples; 988 989 /* we want the time at the end -- but the file format stores 990 time at the start of the chunk. */ 991 // even with timestretch, timecode is still calculated from original 992 // sample count 993 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 994 1071 995 } 1072 996 1073 997 void AudioOutputBase::Status() -
mythtv/libs/libmyth/audiosettings.h
32 32 int audio_samplerate, 33 33 AudioOutputSource audio_source, 34 34 bool audio_set_initial_vol, 35 bool audio_use_passthru, 36 void *audio_codec = NULL); 35 bool audio_use_passthru); 37 36 38 37 AudioSettings(int audio_bits, 39 38 int audio_channels, 40 39 int audio_samplerate, 41 bool audio_use_passthru, 42 void *audio_codec = NULL); 40 bool audio_use_passthru); 43 41 44 42 void FixPassThrough(void); 45 43 void TrimDeviceType(void); … … 57 55 int samplerate; 58 56 bool set_initial_vol; 59 57 bool use_passthru; 60 void *codec;61 58 AudioOutputSource source; 62 59 }; 63 60 -
mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
29 29 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 30 30 audio_bytes_per_sample(0), 31 31 av_context(NULL), 32 outbuf (NULL),33 outbuf_size(0),34 frame_buffer(NULL),35 one_frame_bytes(0)32 outbuflen(0), 33 inbuflen(0), 34 one_frame_bytes(0), 35 reorder(true) 36 36 { 37 37 } 38 38 … … 49 49 av_free(av_context); 50 50 av_context = NULL; 51 51 } 52 53 if (outbuf)54 {55 delete [] outbuf;56 outbuf = NULL;57 outbuf_size = 0;58 }59 60 if (frame_buffer)61 {62 delete [] frame_buffer;63 frame_buffer = NULL;64 one_frame_bytes = 0;65 }66 52 } 67 53 68 54 //CODEC_ID_AC3 69 55 bool AudioOutputDigitalEncoder::Init( 70 CodecID codec_id, int bitrate, int samplerate, int channels )56 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 71 57 { 72 58 AVCodec *codec; 73 59 int ret; 74 60 75 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")61 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5") 76 62 .arg(codec_id_string(codec_id)) 77 63 .arg(bitrate) 78 64 .arg(samplerate) 79 .arg(channels)); 65 .arg(channels) 66 .arg(reencoding)); 67 68 reorder = !reencoding; 80 69 81 //codec = avcodec_find_encoder(codec_id); 70 // We need to do this when called from mythmusic 71 avcodec_init(); 72 avcodec_register_all(); 82 73 // always AC3 as there is no DTS encoder at the moment 2005/1/9 83 74 codec = avcodec_find_encoder(CODEC_ID_AC3); 84 75 if (!codec) … … 107 98 audio_bytes_per_sample = bytes_per_frame; 108 99 one_frame_bytes = bytes_per_frame * av_context->frame_size; 109 100 110 outbuf_size = 16384; // ok for AC3 but DTS?111 outbuf = new char [outbuf_size];112 101 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 113 102 .arg(av_context->frame_size) 114 103 .arg(bytes_per_frame) … … 253 242 254 243 } AESHeader; 255 244 245 void reorder_6ch_ac3(void *buf, unsigned int len) { 246 unsigned short *src = (unsigned short *)buf; 247 unsigned short tmp; 248 unsigned int samples = len >> 1; 249 250 for (uint i = 0; i < samples; i += 6) { 251 tmp = src[i+4]; 252 src[i+4] = src[i+3]; 253 src[i+3] = src[i+2]; 254 src[i+2] = src[i+1]; 255 src[i+1] = tmp; 256 } 257 } 258 256 259 static int encode_frame( 257 260 bool dts, 258 261 unsigned char *data, 259 size_t &len)262 size_t enc_len) 260 263 { 261 264 unsigned char *payload = data + 8; // skip header, currently 52 or 54bits 262 size_t enc_len;263 265 int flags, sample_rate, bit_rate; 264 266 265 267 // we don't do any length/crc validation of the AC3 frame here; presumably … … 270 272 // ignore, and if so, may as well just assume that it will ignore 271 273 // anything with a bad CRC... 272 274 273 uint nr_samples = 0, block_len; 275 uint nr_samples = 0, block_len = 0; 276 274 277 if (dts) 275 278 { 276 279 enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate); … … 305 308 #endif 306 309 } 307 310 308 if (enc_len == 0 || enc_len > len)309 {310 int l = len;311 len = 0;312 return l;313 }314 315 311 enc_len = std::min((uint)enc_len, block_len - 8); 316 312 317 313 //uint32_t x = *(uint32_t*)payload; … … 364 360 data[6] = (enc_len << 3) & 0xFF; 365 361 data[7] = (enc_len >> 5) & 0xFF; 366 362 memset(payload + enc_len, 0, block_len - 8 - enc_len); 367 len = block_len;368 363 369 364 return enc_len; 370 365 } 371 366 372 367 // must have exactly 1 frames worth of data 373 size_t AudioOutputDigitalEncoder::Encode( short *buff)368 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 374 369 { 375 int encsize = 0;376 370 size_t outsize = 0; 377 371 378 // put data in the correct spot for encode frame 379 outsize = avcodec_encode_audio( 380 av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff); 372 int fs = FrameSize(); 373 memcpy(inbuf+inbuflen, buf, len); 374 inbuflen += len; 375 int frames = inbuflen / fs; 381 376 382 size_t tmpsize = outsize; 377 while (frames--) 378 { 379 if (reorder) 380 reorder_6ch_ac3(inbuf, fs); 381 382 // put data in the correct spot for encode frame 383 outsize = avcodec_encode_audio( 384 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 385 386 encode_frame( 387 /*av_context->codec_id==CODEC_ID_DTS*/ false, 388 (unsigned char*)outbuf + outbuflen, outsize 389 ); 383 390 384 outsize = MAX_AC3_FRAME_SIZE; 385 encsize = encode_frame( 386 /*av_context->codec_id==CODEC_ID_DTS*/ false, 387 (unsigned char*)outbuf, outsize); 391 outbuflen += MAX_AC3_FRAME_SIZE; 392 inbuflen -= fs; 393 memmove(inbuf, inbuf+fs, inbuflen); 394 } 395 396 return outbuflen; 397 } 388 398 389 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 390 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 391 .arg(tmpsize).arg(encsize).arg(outsize)); 392 393 return outsize; 399 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 400 { 401 int len = (maxlen < outbuflen ? maxlen : outbuflen); 402 memcpy(ptr, outbuf, len); 403 outbuflen -= len; 404 memmove(outbuf, outbuf+len, outbuflen); 394 405 } -
mythtv/libs/libmyth/audiooutput.h
68 68 69 69 virtual void bufferOutputData(bool y) = 0; 70 70 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 71 virtual bool ToggleUpmix(void) = 0; 71 72 72 73 protected: 73 74 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: 11 14 AudioOutputDigitalEncoder(void); 12 15 ~AudioOutputDigitalEncoder(); 13 16 14 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 17 bool Init(CodecID codec_id, int bitrate, int samplerate, 18 int channels, bool reencoding); 15 19 void Dispose(void); 16 size_t Encode(short * buff); 17 18 inline char *GetFrameBuffer(void); 20 size_t Encode(void *buf, int len); 21 void GetFrames(void *ptr, int maxlen); 19 22 size_t FrameSize(void) const { return one_frame_bytes; } 20 char *GetOutBuff(void) const { return outbuf;}23 int Buffered(void) const { return inbuflen; } 21 24 22 25 public: 23 26 size_t audio_bytes_per_sample; 24 27 25 28 private: 26 29 AVCodecContext *av_context; 27 char *outbuf; 28 int outbuf_size; 29 char *frame_buffer; 30 char outbuf[OUTBUFSIZE]; 31 char inbuf[INBUFSIZE]; 32 int outbuflen; 33 int inbuflen; 30 34 size_t one_frame_bytes; 35 bool reorder; 31 36 }; 32 37 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 38 #endif -
mythtv/libs/libmyth/audiooutputalsa.h
67 67 virtual int GetBufferedOnSoundcard(void) const; 68 68 69 69 private: 70 void SetIECStatus(bool audio); 70 71 inline int SetParameters(snd_pcm_t *handle, 71 72 snd_pcm_format_t format, unsigned int channels, 72 73 unsigned int rate, unsigned int buffer_time, -
mythtv/libs/libmythfreesurround/el_processor.cpp
40 40 41 41 const float PI = 3.141592654; 42 42 const float epsilon = 0.000001; 43 //const float center_level = 0.5*sqrt(0.5); // gain of the center channel 44 //const float center_level = sqrt(0.5); // gain of the center channel 45 const float center_level = 1.0; // gain of the center channel 46 //const float center_level = 0.5; // gain of the center channel 43 const float center_level = 0.5*sqrt(0.5); 47 44 48 // should be .6-.749 // but with centerlevel 2x what its supposed to be, we halve 0.6850 // to keep center from clipping51 //const float window_gain = 0.34;52 //const float window_gain = 0.68;53 const float window_gain = 0.95; // to prive a bit of margin54 55 45 // private implementation of the surround decoder 56 46 class decoder_impl { 57 47 public: … … 98 88 outbuf[c].resize(N); 99 89 filter[c].resize(N); 100 90 } 101 // DC component of filters is always 0102 for (unsigned c=0;c<5;c++)103 {104 filter[c][0] = 0.0;105 filter[c][1] = 0.0;106 filter[c][halfN] = 0.0;107 }108 91 sample_rate(48000); 109 92 // generate the window function (square root of hann, b/c it is applied before and after the transform) 110 93 wnd.resize(N); 111 // dft normalization included in the window for zero cost scaling 112 // also add a gain factor of *2 due to processing gain in algo (see center_level) 113 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); 114 96 current_buf = 0; 115 97 // set the default coefficients 116 98 surround_coefficients(0.8165,0.5774); … … 192 174 // set lfe filter params 193 175 void sample_rate(unsigned int srate) { 194 176 // lfe filter is just straight through band limited 195 unsigned int cutoff = ( 250*N)/srate;177 unsigned int cutoff = (30*N)/srate; 196 178 for (unsigned f=0;f<=halfN;f++) { 197 if ( (f>=2) && (f<cutoff))198 filter[5][f] = 1.0;179 if (f<cutoff) 180 filter[5][f] = 0.5*sqrt(0.5); 199 181 else 200 182 filter[5][f] = 0.0; 201 183 } … … 214 196 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 215 197 } 216 198 217 void surround_gain(float gain) {218 master_gain = gain * window_gain * 0.5 * 0.25;219 for (unsigned k=0;k<N;k++)220 wnd[k] = sqrt(master_gain*(1-cos(2*PI*k/N))/N);221 }222 223 199 // set the phase shifting mode 224 200 void phase_mode(unsigned mode) { 225 201 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; … … 290 266 291 267 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 292 268 // but dont do DC or N/2 component 293 for (unsigned f= 2;f<halfN;f++) {269 for (unsigned f=0;f<halfN;f++) { 294 270 // get left/right amplitudes/phases 295 271 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 296 272 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); … … 305 281 phaseDiff = abs(phaseDiff); 306 282 307 283 if (linear_steering) { 308 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);309 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */310 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();311 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);312 313 /*314 Problem:315 This assumes that the values are interpolated linearly between the cardinal points.316 But this way we have no chance of knowing the average volume...317 - Can we solve that computing everything under the assumption of normalized volume?318 No. Seemingly not.319 - Maybe we should add w explitcitly into the equation and see if we can solve it...320 */321 322 323 //cfloat lt(0.5,0),rt(0.5,0);324 //cfloat x(0,0), y(1,0);325 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);326 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);327 cfloat s = sqrt(p*p/4.0f - q);328 cfloat x = -p;329 cfloat x1 = -p/2.0f + s;330 cfloat x2 = -p/2.0f - s;331 float x = 0;332 if (x1.real() >= -1 && x1.real() <= 1)333 x = x1.real();334 else if (x2.real() >= -1 && x2.real() <= 1)335 x = x2.real();*/336 337 //cfloat yp = (rt - (x*E+H))/(F+x*G);338 //cfloat xp = (lt - (y*B+D))/(A+y*C);339 340 /*xfs[f] = x;341 yfs[f] = y.real();*/342 343 284 // --- this is the fancy new linear mode --- 344 285 345 286 // get sound field x/y position … … 597 538 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 598 539 float surround_balance; // the xfs balance that follows from the coeffs 599 540 float surround_level; // gain for the surround channels (follows from the coeffs 600 float master_gain; // gain for all channels601 541 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 602 542 float front_separation; // front stereo separation 603 543 float rear_separation; // rear stereo separation … … 625 565 626 566 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 627 567 628 void fsurround_decoder::gain(float gain) { impl->surround_gain(gain); }629 630 568 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 631 569 632 570 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 … … 655 650 { 656 651 if (decoder) 657 652 { 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 653 decoder->decode(params.center_width/100.0,params.dimension/100.0); 669 654 } 670 655 } -
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 51 // 0 = (+0°,+0°) - music mode 55 52 // 1 = (+0°,+180°) - PowerDVD compatibility -
mythtv/programs/mythfrontend/globalsettings.cpp
119 119 return gc; 120 120 } 121 121 122 static HostComboBox *SRCQuality() 123 { 124 HostComboBox *gc = new HostComboBox("SRCQuality", false); 125 gc->setLabel(QObject::tr("Sample Rate Conversion")); 126 gc->addSelection(QObject::tr("Best"), "3", true); // default 127 gc->addSelection(QObject::tr("Medium"), "2"); 128 gc->addSelection(QObject::tr("Fastest"), "1"); 129 gc->addSelection(QObject::tr("Disabled"), "0"); 130 gc->setHelpText( 131 QObject::tr( 132 "Set the quality of audio sample rate conversion. " 133 "This only affects non 48000Hz PCM audio. " 134 "All three options offer a worst-case SNR of 97dB. " 135 "'Best' at a bandwidth of 97%. " 136 "'Medium' at a bandwidth of 90%. " 137 "'Fastest' at a bandwidth of 80%. " 138 "Set 'Disabled' only if you know what you are doing.")); 139 return gc; 140 } 141 142 122 143 static HostComboBox *PassThroughOutputDevice() 123 144 { 124 145 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3442 3463 3443 3464 addChild(MaxAudioChannels()); 3444 3465 addChild(AudioUpmixType()); 3466 addChild(SRCQuality()); 3445 3467 3446 3468 // General boolean settings 3447 3469 addChild(AC3PassThrough()); -
mythtv/programs/mythtranscode/transcode.cpp
221 221 // Do nothing 222 222 return kMuteOff; 223 223 } 224 virtual bool ToggleUpmix(void) 225 { 226 // Do nothing 227 return false; 228 } 224 229 225 230 // These are pure virtual in AudioOutput, but we don't need them here 226 231 virtual void bufferOutputData(bool){ return; }