Ticket #5900: audioencoding-trunk-7.5.diff
File audioencoding-trunk-7.5.diff, 87.1 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/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); 361 363 m_output->setBufferSize(256 * 1024); 362 364 m_output->SetBlocking(false); 363 365 -
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
495 495 #endif 496 496 GetNVP()->SetAudioParams(extradata.audio_bits_per_sample, 497 497 extradata.audio_channels, 498 CODEC_ID_NONE, 498 499 extradata.audio_sample_rate, 499 500 false /* AC3/DTS pass through */); 500 501 GetNVP()->ReinitAudio(); -
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
219 219 audioOutput(NULL), 220 220 audio_main_device(QString::null), 221 221 audio_passthru_device(QString::null), 222 audio_channels(2), audio_ bits(-1),223 audio_ samplerate(44100), audio_stretchfactor(1.0f),224 audio_ codec(NULL),audio_lock(QMutex::Recursive),222 audio_channels(2), audio_codec(0), 223 audio_bits(-1), audio_samplerate(44100), 224 audio_stretchfactor(1.0f), audio_lock(QMutex::Recursive), 225 225 // Picture-in-Picture stuff 226 226 pip_active(false), pip_visible(true), 227 227 // Preview window support … … 922 922 audioOutput = AudioOutput::OpenAudio(audio_main_device, 923 923 audio_passthru_device, 924 924 audio_bits, audio_channels, 925 audio_ samplerate,925 audio_codec, audio_samplerate, 926 926 AUDIOOUTPUT_VIDEO, 927 927 setVolume, audio_passthru); 928 928 if (!audioOutput) … … 950 950 951 951 if (audioOutput) 952 952 { 953 const AudioSettings settings( 954 audio_bits, audio_channels, audio_samplerate, 955 audio_passthru, audio_codec); 953 const AudioSettings settings(audio_bits, audio_channels, audio_codec, 954 audio_samplerate, audio_passthru); 956 955 audioOutput->Reconfigure(settings); 956 if (audio_passthru) 957 audio_channels = 2; 957 958 errMsg = audioOutput->GetError(); 958 959 if (!errMsg.isEmpty()) 959 960 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3903 3904 return !IsErrored(); 3904 3905 } 3905 3906 3906 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, 3907 void NuppelVideoPlayer::SetAudioParams(int bps, int channels, int codec, 3907 3908 int samplerate, bool passthru) 3908 3909 { 3909 3910 audio_bits = bps; 3910 3911 audio_channels = channels; 3912 audio_codec = codec; 3911 3913 audio_samplerate = samplerate; 3912 3914 audio_passthru = passthru; 3913 3915 } 3914 3916 3915 void NuppelVideoPlayer::SetAudioCodec(void *ac)3916 {3917 audio_codec = ac;3918 }3919 3920 3917 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3921 3918 { 3922 3919 if (audioOutput) … … 5340 5337 } 5341 5338 } 5342 5339 5340 bool NuppelVideoPlayer::ToggleUpmix() 5341 { 5342 if (audioOutput) 5343 return audioOutput->ToggleUpmix(); 5344 return false; 5345 } 5346 5343 5347 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5344 5348 { 5345 5349 if (videoOutput) -
mythtv/libs/libmythtv/avformatdecoder.cpp
462 462 audioSamples(NULL), 463 463 allow_ac3_passthru(false), allow_dts_passthru(false), 464 464 disable_passthru(false), max_channels(2), 465 dummy_frame(NULL),465 last_ac3_channels(0), dummy_frame(NULL), 466 466 // DVD 467 467 lastdvdtitle(-1), 468 468 decodeStillFrame(false), … … 2024 2024 // waiting on audio. 2025 2025 if (GetNVP()->HasAudioIn() && tracks[kTrackTypeAudio].empty()) 2026 2026 { 2027 GetNVP()->SetAudioParams(-1, -1, -1, false /* AC3/DTS pass-through */);2027 GetNVP()->SetAudioParams(-1, -1, CODEC_ID_NONE, -1, false /* AC3/DTS pass-through */); 2028 2028 GetNVP()->ReinitAudio(); 2029 2029 if (ringBuffer && ringBuffer->isDVD()) 2030 2030 audioIn = AudioInfo(); … … 3059 3059 { 3060 3060 int idx = atracks[i].av_stream_index; 3061 3061 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 3062 AudioInfo item(codec_ctx->codec_id, 3069 3063 codec_ctx->sample_rate, codec_ctx->channels, 3070 do_ac3_passthru || do_dts_passthru);3064 DoPassThrough(codec_ctx)); 3071 3065 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 3072 3066 } 3073 3067 #endif … … 3201 3195 bool AvFormatDecoder::GetFrame(int onlyvideo) 3202 3196 { 3203 3197 AVPacket *pkt = NULL; 3198 AC3HeaderInfo hdr; 3204 3199 int len; 3205 3200 unsigned char *ptr; 3206 3201 int data_size = 0; … … 3631 3626 reselectAudioTrack = true; 3632 3627 } 3633 3628 3634 bool do_ac3_passthru =3635 (allow_ac3_passthru && !transcoding &&3636 (curstream->codec->codec_id == CODEC_ID_AC3));3637 bool do_dts_passthru =3638 (allow_dts_passthru && !transcoding &&3639 (curstream->codec->codec_id == CODEC_ID_DTS));3640 bool using_passthru = do_ac3_passthru || do_dts_passthru;3641 3642 3629 // detect channels on streams that need 3643 3630 // to be decoded before we can know this 3644 3631 bool already_decoded = false; … … 3649 3636 QString("Setting channels to %1") 3650 3637 .arg(audioOut.channels)); 3651 3638 3652 if ( using_passthru)3639 if (DoPassThrough(curstream->codec)) 3653 3640 { 3654 3641 // for passthru let it select the max number 3655 3642 // of channels … … 3671 3658 reselectAudioTrack |= curstream->codec->channels; 3672 3659 } 3673 3660 3661 if (curstream->codec->codec_id == CODEC_ID_AC3) 3662 { 3663 GetBitContext gbc; 3664 init_get_bits(&gbc, ptr, len * 8); 3665 if (!ff_ac3_parse_header(&gbc, &hdr)) 3666 { 3667 if (hdr.channels != last_ac3_channels) 3668 { 3669 last_ac3_channels = curstream->codec->channels = hdr.channels; 3670 SetupAudioStream(); 3671 } 3672 } 3673 } 3674 3674 3675 if (reselectAudioTrack) 3675 3676 { 3676 3677 QMutexLocker locker(&avcodeclock); … … 4196 4197 } 4197 4198 } 4198 4199 4200 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 4201 { 4202 bool passthru = false; 4203 4204 if (ctx->codec_id == CODEC_ID_AC3) 4205 passthru = allow_ac3_passthru && 4206 ctx->channels >= (int)max_channels; 4207 else if (ctx->codec_id == CODEC_ID_DTS) 4208 passthru = allow_dts_passthru; 4209 4210 passthru &= !transcoding && !disable_passthru; 4211 // Don't know any cards that support spdif clocked at < 44100 4212 // Some US cable transmissions have 2ch 32k AC-3 streams 4213 passthru &= ctx->sample_rate >= 44100; 4214 4215 return passthru; 4216 } 4217 4199 4218 /** \fn AvFormatDecoder::SetupAudioStream(void) 4200 4219 * \brief Reinitializes audio if it needs to be reinitialized. 4201 4220 * … … 4209 4228 AVStream *curstream = NULL; 4210 4229 AVCodecContext *codec_ctx = NULL; 4211 4230 AudioInfo old_in = audioIn; 4212 AudioInfo old_out = audioOut;4213 4231 bool using_passthru = false; 4214 4232 4215 4233 if ((currentTrack[kTrackTypeAudio] >= 0) && … … 4223 4241 codec_ctx = curstream->codec; 4224 4242 if (codec_ctx) 4225 4243 { 4226 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4227 (codec_ctx->codec_id == CODEC_ID_AC3)); 4228 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4229 (codec_ctx->codec_id == CODEC_ID_DTS)); 4230 using_passthru = do_ac3_passthru || do_dts_passthru; 4231 info = AudioInfo(codec_ctx->codec_id, 4232 codec_ctx->sample_rate, codec_ctx->channels, 4233 using_passthru && !disable_passthru); 4244 using_passthru = DoPassThrough(codec_ctx); 4245 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4246 codec_ctx->channels, using_passthru); 4234 4247 } 4235 4248 } 4236 4249 … … 4247 4260 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4248 4261 4249 4262 audioOut = audioIn = info; 4250 AudioInfo tmpAudioOut = audioOut;4251 4263 4252 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4253 if (using_passthru && !disable_passthru) 4264 if (!using_passthru && audioOut.channels > (int)max_channels) 4254 4265 { 4255 tmpAudioOut.channels = 2; 4256 tmpAudioOut.sample_rate = 48000; 4257 tmpAudioOut.sample_size = 4; 4258 } 4259 4260 if (audioOut.channels > (int) max_channels) 4261 { 4262 audioOut.channels = (int) max_channels; 4266 audioOut.channels = (int)max_channels; 4263 4267 audioOut.sample_size = audioOut.channels * 2; 4264 codec_ctx->channels 4268 codec_ctx->channels = audioOut.channels; 4265 4269 } 4266 4270 4267 if (!using_passthru)4268 tmpAudioOut = audioOut;4269 4270 4271 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4271 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4272 .arg((using_passthru) ? "digital passthrough " : "") 4273 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4274 .arg(old_in.toString()).arg(old_out.toString()) 4275 .arg(audioIn.toString()).arg(audioOut.toString())); 4272 QString("\n\t\t\tfrom %1 to %2") 4273 .arg(old_in.toString()).arg(audioOut.toString())); 4276 4274 4277 if ( tmpAudioOut.sample_rate > 0)4278 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4275 if (audioOut.sample_rate > 0) 4276 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4279 4277 4280 GetNVP()->SetAudioParams(tmpAudioOut.bps(), tmpAudioOut.channels, 4281 tmpAudioOut.sample_rate, audioIn.do_passthru); 4278 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4279 audioOut.codec_id, audioOut.sample_rate, 4280 audioOut.do_passthru); 4282 4281 4283 // allow the audio stuff to reencode4284 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4285 4282 GetNVP()->ReinitAudio(); 4286 4283 4287 4284 return true; -
mythtv/libs/libmythtv/tv_play.h
429 429 bool TimeStretchHandleAction(PlayerContext*, 430 430 const QStringList &actions); 431 431 432 void ToggleUpmix(PlayerContext*); 432 433 void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true); 433 434 bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions); 434 435 -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
126 126 void SetAudioStretchFactor(float factor) { audio_stretchfactor = factor; } 127 127 void SetAudioOutput(AudioOutput *ao) { audioOutput = ao; } 128 128 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 129 void SetAudioParams(int bits, int channels, int samplerate, bool passthru);129 void SetAudioParams(int bits, int channels, int codec, int samplerate, bool passthru); 130 130 void SetEffDsp(int dsprate); 131 131 uint AdjustVolume(int change); 132 132 bool SetMuted(bool mute); … … 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; } … … 715 716 QString audio_main_device; 716 717 QString audio_passthru_device; 717 718 int audio_channels; 719 int audio_codec; 718 720 int audio_bits; 719 721 int audio_samplerate; 720 722 float audio_stretchfactor; 721 void *audio_codec;722 723 bool audio_passthru; 723 724 QMutex audio_lock; 724 725 -
mythtv/libs/libmythtv/tv_play.cpp
491 491 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 492 492 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 493 493 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 494 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 494 495 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture view", 495 496 "V"); 496 497 REG_KEY("TV Playback", "TOGGLEPBPMODE", "Toggle Picture-by-Picture view", … … 630 631 Teletext F2,F3,F4,F5,F6,F7,F8 631 632 ITV F2,F3,F4,F5,F6,F7,F12 632 633 633 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 634 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 634 635 */ 635 636 } 636 637 … … 4353 4354 DoTogglePictureAttribute(ctx, kAdjustingPicture_Playback); 4354 4355 else if (has_action("TOGGLESTRETCH", actions)) 4355 4356 ToggleTimeStretch(ctx); 4357 else if (has_action("TOGGLEUPMIX", actions)) 4358 ToggleUpmix(ctx); 4356 4359 else if (has_action("TOGGLESLEEP", actions)) 4357 4360 ToggleSleepTimer(ctx); 4358 4361 else if (has_action("TOGGLERECORD", actions) && islivetv) … … 8039 8042 SetSpeedChangeTimer(0, __LINE__); 8040 8043 } 8041 8044 8045 void TV::ToggleUpmix(PlayerContext *ctx) 8046 { 8047 if (!ctx->nvp || !ctx->nvp->HasAudioOut()) 8048 return; 8049 QString text; 8050 if (ctx->nvp->ToggleUpmix()) 8051 text = tr("Upmixer On"); 8052 else 8053 text = tr("Upmixer Off"); 8054 8055 if (ctx->nvp->GetOSD() && !browsemode) 8056 ctx->nvp->GetOSD()->SetSettingsText(text, 5); 8057 } 8058 8042 8059 // dir in 10ms jumps 8043 8060 void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit) 8044 8061 { … … 9668 9685 SetManualZoom(actx, true, tr("Zoom Mode ON")); 9669 9686 else if (action == "TOGGLESTRETCH") 9670 9687 ToggleTimeStretch(actx); 9688 else if (action == "TOGGLEUPMIX") 9689 ToggleUpmix(actx); 9671 9690 else if (action.left(13) == "ADJUSTSTRETCH") 9672 9691 { 9673 9692 bool floatRead; … … 10033 10052 10034 10053 if (category == "AUDIOSYNC") 10035 10054 new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC"); 10055 else if (category == "TOGGLEUPMIX") 10056 new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 10036 10057 else if (category == "TIMESTRETCH") 10037 10058 FillMenuTimeStretch(ctx, treeMenu); 10038 10059 else if (category == "VIDEOSCAN") -
mythtv/libs/libmythtv/tvosdmenuentry.cpp
232 232 curMenuEntries.append( 233 233 new TVOSDMenuEntry("AUDIOSYNC", 1, 1, 1, 1 , "Audio Sync")); 234 234 curMenuEntries.append( 235 new TVOSDMenuEntry("TOGGLEUPMIX", 1, 1, 1, 1, "Toggle Upmixer")); 236 curMenuEntries.append( 235 237 new TVOSDMenuEntry("TIMESTRETCH", 1, 1, 1, 1, "Time Stretch")); 236 238 curMenuEntries.append( 237 239 new TVOSDMenuEntry("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(); … … 260 261 bool allow_dts_passthru; 261 262 bool disable_passthru; 262 263 uint max_channels; 264 uint last_ac3_channels; 263 265 264 266 VideoFrame *dummy_frame; 265 267 -
mythtv/libs/libavcodec/aac.c
98 98 static VLC vlc_scalefactors; 99 99 static VLC vlc_spectral[11]; 100 100 101 #define CHAN_MAP_MAX 6 101 102 103 static int chan_map[CHAN_MAP_MAX] = { 2, 0, 6, 4, 3, 2 }; 104 105 102 106 static ChannelElement* get_che(AACContext *ac, int type, int elem_id) { 103 107 static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0 }; 104 108 if (ac->tag_che_map[type][elem_id]) { … … 167 171 /* Allocate or free elements depending on if they are in the 168 172 * current program configuration. 169 173 * 170 * Set up default 1:1output mapping.174 * Set up default SMPTE output mapping. 171 175 * 172 * For a 5.1 stream the output order will be:173 * [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ]174 176 */ 175 177 176 178 for(i = 0; i < MAX_ELEM_ID; i++) { … … 179 181 if(!ac->che[type][i] && !(ac->che[type][i] = av_mallocz(sizeof(ChannelElement)))) 180 182 return AVERROR(ENOMEM); 181 183 if(type != TYPE_CCE) { 182 ac->output_data[channels++] = ac->che[type][i]->ch[0].ret; 183 if(type == TYPE_CPE) { 184 ac->output_data[channels++] = ac->che[type][i]->ch[1].ret; 184 /* Convert to SMPTE channel order */ 185 int ch = 0; 186 if (che_pos[type][i] < CHAN_MAP_MAX) { 187 if (che_pos[type][i] == AAC_CHANNEL_FRONT) 188 ch == TYPE_SCE ? /* center */ 2 : /* FL */ 0; 189 else 190 ch = chan_map[che_pos[type][i]]; 191 ac->output_data[ch] = ac->che[type][i]->ch[0].ret; 192 channels++; 193 if(type == TYPE_CPE) { 194 ac->output_data[ch + 1] = ac->che[type][i]->ch[1].ret; 195 channels++; 196 } 185 197 } 198 else { 199 ac->output_data[channels++] = ac->che[type][i]->ch[0].ret; 200 if(type == TYPE_CPE) { 201 ac->output_data[channels++] = ac->che[type][i]->ch[1].ret; 202 } 203 } 186 204 } 187 205 } else 188 206 av_freep(&ac->che[type][i]); -
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
12 12 passthru_device(QString::null), 13 13 bits(-1), 14 14 channels(-1), 15 codec(0), 15 16 samplerate(-1), 16 17 set_initial_vol(false), 17 18 use_passthru(false), 18 codec(NULL),19 19 source(AUDIOOUTPUT_UNKNOWN) 20 20 { 21 21 } … … 25 25 passthru_device(other.passthru_device), 26 26 bits(other.bits), 27 27 channels(other.channels), 28 codec(other.codec), 28 29 samplerate(other.samplerate), 29 30 set_initial_vol(other.set_initial_vol), 30 31 use_passthru(other.use_passthru), 31 codec(other.codec),32 32 source(other.source) 33 33 { 34 34 } … … 38 38 const QString &audio_passthru_device, 39 39 int audio_bits, 40 40 int audio_channels, 41 int audio_codec, 41 42 int audio_samplerate, 42 43 AudioOutputSource audio_source, 43 44 bool audio_set_initial_vol, 44 bool audio_use_passthru, 45 void *audio_codec) : 45 bool audio_use_passthru) : 46 46 main_device(audio_main_device), 47 47 passthru_device(audio_passthru_device), 48 48 bits(audio_bits), 49 49 channels(audio_channels), 50 codec(audio_codec), 50 51 samplerate(audio_samplerate), 51 52 set_initial_vol(audio_set_initial_vol), 52 53 use_passthru(audio_use_passthru), 53 codec(audio_codec),54 54 source(audio_source) 55 55 { 56 56 } … … 58 58 AudioSettings::AudioSettings( 59 59 int audio_bits, 60 60 int audio_channels, 61 int audio_codec, 61 62 int audio_samplerate, 62 bool audio_use_passthru, 63 void *audio_codec) : 63 bool audio_use_passthru) : 64 64 main_device(QString::null), 65 65 passthru_device(QString::null), 66 66 bits(audio_bits), 67 67 channels(audio_channels), 68 codec(audio_codec), 68 69 samplerate(audio_samplerate), 69 70 set_initial_vol(false), 70 71 use_passthru(audio_use_passthru), 71 codec(audio_codec),72 72 source(AUDIOOUTPUT_UNKNOWN) 73 73 { 74 74 } -
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 … … 85 86 virtual void WriteAudio(unsigned char *aubuf, int size) = 0; 86 87 virtual int GetSpaceOnSoundcard(void) const = 0; 87 88 virtual int GetBufferedOnSoundcard(void) const = 0; 89 virtual vector<int> GetSupportedRates(void) 90 { vector<int> rates; return rates; } 88 91 /// You need to call this from any implementation in the dtor. 89 92 void KillAudio(void); 90 93 … … 122 125 123 126 // Basic details about the audio stream 124 127 int audio_channels; 128 int audio_codec; 125 129 int audio_bytes_per_sample; 126 130 int audio_bits; 127 131 int audio_samplerate; … … 132 136 QString audio_passthru_device; 133 137 134 138 bool audio_passthru; 139 bool audio_enc; 140 bool audio_reenc; 135 141 136 142 float audio_stretchfactor; 137 AVCodecContext *audio_codec;138 143 AudioOutputSource source; 139 144 140 145 bool killaudio; … … 144 149 bool buffer_output_data_for_use; // used by AudioOutputNULL 145 150 146 151 int configured_audio_channels; 152 int orig_config_channels; 153 int src_quality; 147 154 148 155 private: 149 156 // resampler … … 156 163 FreeSurround *upmixer; 157 164 158 165 int source_audio_channels; 166 int source_audio_samplerate; 159 167 int source_audio_bytes_per_sample; 160 168 bool needs_upmix; 161 169 int surround_mode; 170 bool allow_ac3_passthru; 171 float old_audio_stretchfactor; 162 172 163 173 bool blocking; // do AddSamples calls block? 164 174 -
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)); … … 146 266 } 147 267 } 148 268 269 void AudioOutputALSA::ReorderSmpteToAlsa6ch(unsigned char *buf, int size) 270 { 271 if (audio_bits == 8) 272 _ReorderSmpteToAlsa6ch(buf, size); 273 else if (audio_bits == 16) 274 _ReorderSmpteToAlsa6ch((short *)buf, size / sizeof(short)); 275 } 149 276 277 template <class AudioDataType> 278 void AudioOutputALSA::_ReorderSmpteToAlsa6ch(AudioDataType *buf, int size) 279 { 280 AudioDataType tmpC, tmpLFE; 281 282 for (int i = 0; i < size; i+= 6) { 283 tmpC = buf[i+2]; 284 tmpLFE = buf[i+3]; 285 buf[i+2] = buf[i+4]; 286 buf[i+3] = buf[i+5]; 287 buf[i+4] = tmpC; 288 buf[i+5] = tmpLFE; 289 } 290 291 } 150 292 void AudioOutputALSA::WriteAudio(unsigned char *aubuf, int size) 151 293 { 152 294 unsigned char *tmpbuf; … … 158 300 VERBOSE(VB_IMPORTANT, QString("WriteAudio() called with pcm_handle == NULL!")); 159 301 return; 160 302 } 303 304 if (!(audio_passthru || audio_enc) && audio_channels == 6) 305 ReorderSmpteToAlsa6ch(aubuf, size); 306 161 307 162 308 tmpbuf = aubuf; 163 309 -
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
21 21 AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 22 22 // protected 23 23 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),24 audio_channels(-1), audio_codec(CODEC_ID_NONE), 25 audio_bytes_per_sample(0), audio_bits(-1), 26 audio_samplerate(-1), audio_buffer_unused(0), 27 27 fragment_size(0), soundcard_buffer_size(0), 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 || source_audio_channels > 2 || 162 audio_passthru) 163 return false; 164 if (configured_audio_channels == 6) 165 configured_audio_channels = 2; 166 else 167 configured_audio_channels = 6; 168 169 const AudioSettings settings(audio_bits, source_audio_channels, 170 audio_codec, source_audio_samplerate, 171 audio_passthru); 172 Reconfigure(settings); 173 return (configured_audio_channels == 6); 174 } 175 176 186 177 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 178 { 188 179 AudioSettings settings = orig_settings; 189 180 190 int codec_id = CODEC_ID_NONE;191 int lcodec_id = CODEC_ID_NONE;192 int lcchannels = 0;193 int cchannels = 0;194 181 int lsource_audio_channels = settings.channels; 195 182 bool lneeds_upmix = false; 183 bool laudio_reenc = false; 196 184 197 if (settings.codec) 185 // Are we reencoding a (previously) timestretched bitstream? 186 if ((settings.codec == CODEC_ID_AC3 || settings.codec == CODEC_ID_DTS) && 187 !settings.use_passthru && allow_ac3_passthru) 198 188 { 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; 189 laudio_reenc = true; 190 VERBOSE(VB_AUDIO, LOC + "Reencoding decoded AC3/DTS to AC3"); 205 191 } 206 192 207 if (audio_codec) 193 // Enough channels? Upmix if not 194 if (settings.channels < configured_audio_channels && 195 !settings.use_passthru) 208 196 { 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 197 settings.channels = configured_audio_channels; 217 198 lneeds_upmix = true; 218 199 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); … … 224 205 settings.samplerate == audio_samplerate && !need_resampler && 225 206 settings.use_passthru == audio_passthru && 226 207 lneeds_upmix == needs_upmix && 227 l codec_id == codec_id && lcchannels == cchannels);208 laudio_reenc == audio_reenc); 228 209 bool upmix_deps = 229 210 (lsource_audio_channels == source_audio_channels); 230 211 if (general_deps && upmix_deps) … … 251 232 waud = raud = 0; 252 233 audio_actually_paused = false; 253 234 254 bool redo_stretch = (pSoundStretch && audio_channels != settings.channels);255 235 audio_channels = settings.channels; 256 236 source_audio_channels = lsource_audio_channels; 257 237 audio_bits = settings.bits; 258 audio_samplerate = settings.samplerate; 259 audio_codec = (AVCodecContext*)settings.codec; 238 source_audio_samplerate = audio_samplerate = settings.samplerate; 239 audio_reenc = laudio_reenc; 240 audio_codec = settings.codec; 260 241 audio_passthru = settings.use_passthru; 261 242 needs_upmix = lneeds_upmix; 262 243 … … 265 246 Error("AudioOutput only supports 8 or 16bit audio."); 266 247 return; 267 248 } 268 audio_bytes_per_sample = audio_channels * audio_bits / 8; 269 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 249 250 VERBOSE(VB_AUDIO, LOC + QString("Original audio codec was %1") 251 .arg(codec_id_string((CodecID)audio_codec))); 270 252 271 253 need_resampler = false; 272 254 killaudio = false; … … 275 257 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 276 258 277 259 numlowbuffer = 0; 260 261 // Find out what sample rates we can output (if output layer supports it) 262 vector<int> rates = GetSupportedRates(); 263 vector<int>::iterator it; 264 bool resample = true; 278 265 266 for (it = rates.begin(); it < rates.end(); it++) 267 { 268 VERBOSE(VB_AUDIO, LOC + QString("Sample rate %1 is supported") 269 .arg(*it)); 270 if (*it == audio_samplerate) 271 resample = false; 272 } 273 274 // Assume 48k if we can't get supported rates 275 if (rates.empty()) 276 rates.push_back(48000); 277 278 if (resample) 279 { 280 int error; 281 audio_samplerate = *(rates.end()); 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, source_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 299 // Encode to AC-3 if not passing thru , there's > 2 channels 300 // and a passthru device is defined 301 if (!audio_passthru && allow_ac3_passthru && 302 (audio_channels > 2 || audio_reenc)) 303 { 304 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 305 encoder = new AudioOutputDigitalEncoder(); 306 if (!encoder->Init(CODEC_ID_AC3, 448000, audio_samplerate, 307 audio_channels, audio_reenc)) 308 { 309 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 310 delete encoder; 311 encoder = NULL; 312 } 313 314 audio_enc = true; 315 } 316 317 if(audio_passthru || audio_enc) 318 // AC-3 output - soundcard expects a 2ch 48k stream 319 audio_channels = 2; 320 321 audio_bytes_per_sample = audio_channels * audio_bits / 8; 322 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 323 279 324 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 280 325 .arg(audio_main_device).arg(audio_channels) 281 326 .arg(source_audio_channels).arg(audio_samplerate)); … … 309 354 current_seconds = -1; 310 355 source_bitrate = -1; 311 356 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 357 if (needs_upmix) 334 358 { 335 359 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … 344 368 (FreeSurround::SurroundMode)surround_mode); 345 369 346 370 VERBOSE(VB_AUDIO, LOC + 347 QString(" create upmixer done with surround mode %1")371 QString("Create upmixer done with surround mode %1") 348 372 .arg(surround_mode)); 349 373 } 350 374 351 375 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 352 376 .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 377 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 378 SetStretchFactorLocked(old_audio_stretchfactor); 379 404 380 // Setup visualisations, zero the visualisations buffers 405 381 prepareVisuals(); 406 382 … … 436 412 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 437 413 killaudio = true; 438 414 StopOutputThread(); 415 QMutexLocker lock1(&audio_buflock); 439 416 440 417 // Close resampler? 441 418 if (src_ctx) 419 { 442 420 src_delete(src_ctx); 421 src_ctx = NULL; 422 } 423 443 424 need_resampler = false; 444 425 445 426 // close sound stretcher … … 447 428 { 448 429 delete pSoundStretch; 449 430 pSoundStretch = NULL; 431 old_audio_stretchfactor = audio_stretchfactor; 432 audio_stretchfactor = 1.0; 450 433 } 451 434 452 435 if (encoder) … … 461 444 upmixer = NULL; 462 445 } 463 446 needs_upmix = false; 447 audio_enc = false; 464 448 465 449 CloseDevice(); 466 450 … … 611 595 612 596 // include algorithmic latencies 613 597 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 598 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 621 599 audio_bytes_per_sample) / audio_stretchfactor); 622 }623 600 624 601 if (upmixer && needs_upmix) 625 {626 602 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 627 }628 603 604 if (encoder) 605 totalbuffer += encoder->Buffered(); 606 629 607 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 630 608 (audio_bytes_per_sample * effdspstretched)); 631 609 … … 681 659 return false; // would overflow 682 660 } 683 661 662 QMutexLocker lock1(&audio_buflock); 663 684 664 // resample input if necessary 685 665 if (need_resampler && src_ctx) 686 666 { … … 725 705 int abps = (encoder) ? 726 706 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 727 707 int len = samples * abps; 708 709 // Give original samples to mythmusic visualisation 710 dispatchVisual((unsigned char *)buffer, len, timecode, 711 source_audio_channels, audio_bits); 728 712 729 713 // Check we have enough space to write the data 730 714 if (need_resampler && src_ctx) … … 749 733 return false; // would overflow 750 734 } 751 735 736 QMutexLocker lock1(&audio_buflock); 737 752 738 // resample input if necessary 753 739 if (need_resampler && src_ctx) 754 740 { … … 809 795 { 810 796 int error = src_reset(src_ctx); 811 797 if (error) 798 { 812 799 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 813 800 "Error occured while resetting resampler: %1") 814 801 .arg(src_strerror(error))); 802 src_ctx = NULL; 803 } 815 804 } 816 805 } 817 806 } … … 821 810 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 822 811 long long timecode) 823 812 { 824 audio_buflock.lock();825 826 813 int len; // = samples * audio_bytes_per_sample; 827 814 int audio_bytes = audio_bits / 8; 828 815 int org_waud = waud; … … 839 826 .arg(samples * abps) 840 827 .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode) 841 828 .arg(needs_upmix)); 842 829 830 len = WaitForFreeSpace(samples); 831 843 832 if (upmixer && needs_upmix) 844 833 { 845 834 int out_samples = 0; 835 org_waud = waud; 846 836 int step = (interleaved)?source_audio_channels:1; 847 len = WaitForFreeSpace(samples); // test 837 848 838 for (int itemp = 0; itemp < samples; ) 849 839 { 850 // just in case it does a processing cycle, release the lock851 // to allow the output loop to do output852 audio_buflock.unlock();853 840 if (audio_bytes == 2) 854 841 { 855 842 itemp += upmixer->putSamples( … … 866 853 source_audio_channels, 867 854 (interleaved) ? 0 : samples); 868 855 } 869 audio_buflock.lock();870 856 871 857 int copy_samples = upmixer->numSamples(); 872 858 if (copy_samples) … … 900 886 } 901 887 else 902 888 { 903 len = WaitForFreeSpace(samples);904 905 889 if (interleaved) 906 890 { 907 891 char *mybuf = (char*)buffer; … … 936 920 } 937 921 } 938 922 939 if (samples > 0) 923 if (samples <= 0) 924 return; 925 926 if (pSoundStretch) 940 927 { 941 if (pSoundStretch) 928 // does not change the timecode, only the number of samples 929 // back to orig pos 930 org_waud = waud; 931 int bdiff = kAudioRingBufferSize - org_waud; 932 int nSamplesToEnd = bdiff/abps; 933 if (bdiff < len) 942 934 { 935 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 936 (audiobuffer + 937 org_waud), nSamplesToEnd); 938 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 939 (len - bdiff) / abps); 940 } 941 else 942 { 943 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 944 (audiobuffer + org_waud), 945 len / abps); 946 } 943 947 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); 948 int nSamples = pSoundStretch->numSamples(); 949 len = WaitForFreeSpace(nSamples); 950 951 while ((nSamples = pSoundStretch->numSamples())) 952 { 953 if (nSamples > nSamplesToEnd) 954 nSamples = nSamplesToEnd; 955 956 nSamples = pSoundStretch->receiveSamples( 957 (soundtouch::SAMPLETYPE*) 958 (audiobuffer + org_waud), nSamples 959 ); 960 961 if (nSamples == nSamplesToEnd) { 962 org_waud = 0; 963 nSamplesToEnd = kAudioRingBufferSize/abps; 956 964 } 957 else 958 { 959 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 960 (audiobuffer + org_waud), 961 len / abps); 965 else { 966 org_waud += nSamples * abps; 967 nSamplesToEnd -= nSamples; 962 968 } 963 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;971 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 creates979 // a full encoded buffer just like before980 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 else1012 {1013 int newLen = 0;1014 int nSamples;1015 len = WaitForFreeSpace(pSoundStretch->numSamples() *1016 audio_bytes_per_sample);1017 do1018 {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 else1034 {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);1043 }1044 969 } 970 } 1045 971 1046 waud = org_waud; 1047 lastaudiolen = audiolen(false); 972 // Encode to AC-3? 973 if (encoder) 974 { 975 org_waud = waud; 976 int bdiff = kAudioRingBufferSize - org_waud; 977 int to_get = 0; 1048 978 1049 if ( timecode < 0)979 if (bdiff < len) 1050 980 { 1051 // mythmusic doesn't give timestamps..1052 t imecode = (int)((samples_buffered * 100000.0) / effdsp);981 encoder->Encode(audiobuffer + org_waud, bdiff); 982 to_get = encoder->Encode(audiobuffer, len - bdiff); 1053 983 } 1054 1055 samples_buffered += samples; 1056 1057 /* we want the time at the end -- but the file format stores 1058 time at the start of the chunk. */ 1059 // even with timestretch, timecode is still calculated from original 1060 // sample count 1061 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 984 else 985 to_get = encoder->Encode(audiobuffer + org_waud, len); 1062 986 1063 if ( interleaved)987 if (to_get > 0) 1064 988 { 1065 dispatchVisual((unsigned char *)buffer, len, timecode, 1066 source_audio_channels, audio_bits); 989 if (to_get >= bdiff) 990 { 991 encoder->GetFrames(audiobuffer + org_waud, bdiff); 992 to_get -= bdiff; 993 org_waud = 0; 994 } 995 if (to_get > 0) 996 encoder->GetFrames(audiobuffer + org_waud, to_get); 997 998 org_waud += to_get; 1067 999 } 1068 1000 } 1069 1001 1070 audio_buflock.unlock(); 1002 waud = org_waud; 1003 lastaudiolen = audiolen(false); 1004 1005 if (timecode < 0) 1006 // mythmusic doesn't give timestamps.. 1007 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1008 1009 samples_buffered += samples; 1010 1011 /* we want the time at the end -- but the file format stores 1012 time at the start of the chunk. */ 1013 // even with timestretch, timecode is still calculated from original 1014 // sample count 1015 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 1071 1016 } 1072 1017 1073 1018 void AudioOutputBase::Status() -
mythtv/libs/libmyth/audiooutput.cpp
33 33 AudioOutput *AudioOutput::OpenAudio( 34 34 const QString &main_device, 35 35 const QString &passthru_device, 36 int audio_bits, int audio_channels, int audio_samplerate, 36 int audio_bits, int audio_channels, 37 int audio_codec, int audio_samplerate, 37 38 AudioOutputSource source, 38 39 bool set_initial_vol, bool audio_passthru) 39 40 { 40 41 AudioSettings settings( 41 42 main_device, passthru_device, audio_bits, 42 audio_channels, audio_ samplerate, source,43 audio_channels, audio_codec, audio_samplerate, source, 43 44 set_initial_vol, audio_passthru); 44 45 45 46 settings.FixPassThrough(); -
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 bool audio_use_passthru, 36 void *audio_codec = NULL); 36 bool audio_use_passthru); 37 37 38 38 AudioSettings(int audio_bits, 39 39 int audio_channels, 40 int audio_codec, 40 41 int audio_samplerate, 41 bool audio_use_passthru, 42 void *audio_codec = NULL); 42 bool audio_use_passthru); 43 43 44 44 void FixPassThrough(void); 45 45 void TrimDeviceType(void); … … 54 54 public: 55 55 int bits; 56 56 int channels; 57 int codec; 57 58 int samplerate; 58 59 bool set_initial_vol; 59 60 bool use_passthru; 60 void *codec;61 61 AudioOutputSource source; 62 62 }; 63 63 -
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; -
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),38 one_frame_bytes(0)35 outbuflen(0), 36 inbuflen(0), 37 one_frame_bytes(0), 38 reorder(true) 39 39 { 40 40 } 41 41 … … 52 52 av_free(av_context); 53 53 av_context = NULL; 54 54 } 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 55 } 70 56 71 57 //CODEC_ID_AC3 72 58 bool AudioOutputDigitalEncoder::Init( 73 CodecID codec_id, int bitrate, int samplerate, int channels )59 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 74 60 { 75 61 AVCodec *codec; 76 62 int ret; 77 63 78 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")64 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4, re=%5") 79 65 .arg(codec_id_string(codec_id)) 80 66 .arg(bitrate) 81 67 .arg(samplerate) 82 .arg(channels)); 68 .arg(channels) 69 .arg(reencoding)); 70 71 reorder = !reencoding; 83 72 84 //codec = avcodec_find_encoder(codec_id); 73 // We need to do this when called from mythmusic 74 avcodec_init(); 75 avcodec_register_all(); 85 76 // always AC3 as there is no DTS encoder at the moment 2005/1/9 86 77 codec = avcodec_find_encoder(CODEC_ID_AC3); 87 78 if (!codec) … … 110 101 audio_bytes_per_sample = bytes_per_frame; 111 102 one_frame_bytes = bytes_per_frame * av_context->frame_size; 112 103 113 outbuf_size = 16384; // ok for AC3 but DTS?114 outbuf = new char [outbuf_size];115 104 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 116 105 .arg(av_context->frame_size) 117 106 .arg(bytes_per_frame) … … 256 245 257 246 } AESHeader; 258 247 248 void reorder_6ch_ac3(void *buf, unsigned int len) { 249 unsigned short *src = (unsigned short *)buf; 250 unsigned short tmpC, tmpLFE; 251 unsigned int samples = len >> 1; 252 253 for (uint i = 0; i < samples; i += 6) { 254 tmpC = src[i+2]; 255 tmpLFE = src[i+3]; 256 src[i+2] = src[i+4]; 257 src[i+3] = src[i+5]; 258 src[i+4] = tmpC; 259 src[i+5] = tmpLFE; 260 } 261 } 262 259 263 static int encode_frame( 260 264 bool dts, 261 265 unsigned char *data, 262 size_t &len)266 size_t enc_len) 263 267 { 264 268 unsigned char *payload = data + 8; // skip header, currently 52 or 54bits 265 size_t enc_len;266 269 int flags, sample_rate, bit_rate; 267 270 268 271 // we don't do any length/crc validation of the AC3 frame here; presumably … … 273 276 // ignore, and if so, may as well just assume that it will ignore 274 277 // anything with a bad CRC... 275 278 276 uint nr_samples = 0, block_len; 279 uint nr_samples = 0, block_len = 0; 280 277 281 if (dts) 278 282 { 279 283 enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate); … … 302 306 } 303 307 } 304 308 305 if (enc_len == 0 || enc_len > len)306 {307 int l = len;308 len = 0;309 return l;310 }311 312 309 enc_len = std::min((uint)enc_len, block_len - 8); 313 310 314 311 //uint32_t x = *(uint32_t*)payload; … … 361 358 data[6] = (enc_len << 3) & 0xFF; 362 359 data[7] = (enc_len >> 5) & 0xFF; 363 360 memset(payload + enc_len, 0, block_len - 8 - enc_len); 364 len = block_len;365 361 366 362 return enc_len; 367 363 } 368 364 369 // must have exactly 1 frames worth of data 370 size_t AudioOutputDigitalEncoder::Encode(short *buff) 365 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 371 366 { 372 int encsize = 0;373 367 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 368 379 size_t tmpsize = outsize; 369 int fs = FrameSize(); 370 memcpy(inbuf+inbuflen, buf, len); 371 inbuflen += len; 372 int frames = inbuflen / fs; 380 373 381 outsize = MAX_AC3_FRAME_SIZE;382 encsize = encode_frame(383 /*av_context->codec_id==CODEC_ID_DTS*/ false,384 (unsigned char*)outbuf, outsize);374 while (frames--) 375 { 376 if (reorder) 377 reorder_6ch_ac3(inbuf, fs); 385 378 386 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 387 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")388 .arg(tmpsize).arg(encsize).arg(outsize));379 // put data in the correct spot for encode frame 380 outsize = avcodec_encode_audio( 381 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 389 382 390 return outsize; 383 encode_frame( 384 /*av_context->codec_id==CODEC_ID_DTS*/ false, 385 (unsigned char*)outbuf + outbuflen, outsize 386 ); 387 388 outbuflen += MAX_AC3_FRAME_SIZE; 389 inbuflen -= fs; 390 memmove(inbuf, inbuf+fs, inbuflen); 391 } 392 393 return outbuflen; 391 394 } 395 396 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 397 { 398 int len = (maxlen < outbuflen ? maxlen : outbuflen); 399 memcpy(ptr, outbuf, len); 400 outbuflen -= len; 401 memmove(outbuf, outbuf+len, outbuflen); 402 } -
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 21 bool set_initial_vol, bool audio_passthru); 21 22 … … 68 69 69 70 virtual void bufferOutputData(bool y) = 0; 70 71 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 72 virtual bool ToggleUpmix(void) = 0; 71 73 72 74 protected: 73 75 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, int channels, bool reencoding = false); 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; 34 bool reorder; 31 35 }; 32 36 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 37 #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, 73 75 unsigned int period_time); 74 76 75 77 void ReorderSmpteToAlsa6ch(unsigned char *buf, int size); 78 template <class AudioDataType> 79 void _ReorderSmpteToAlsa6ch(AudioDataType *buf, int size); 76 80 // Volume related 77 81 void SetCurrentVolume(QString control, int channel, int volume); 78 82 void OpenMixer(bool setstartingvolume); -
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 // set the default coefficients 117 98 surround_coefficients(0.8165,0.5774); … … 193 174 // set lfe filter params 194 175 void sample_rate(unsigned int srate) { 195 176 // lfe filter is just straight through band limited 196 unsigned int cutoff = ( 250*N)/srate;177 unsigned int cutoff = (30*N)/srate; 197 178 for (unsigned f=0;f<=halfN;f++) { 198 if ( (f>=2) && (f<cutoff))199 filter[5][f] = 1.0;179 if (f<cutoff) 180 filter[5][f] = 0.5*sqrt(0.5); 200 181 else 201 182 filter[5][f] = 0.0; 202 183 } … … 215 196 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 216 197 } 217 198 218 void surround_gain(float gain) {219 master_gain = gain * window_gain * 0.5 * 0.25;220 for (unsigned k=0;k<N;k++)221 wnd[k] = sqrt(master_gain*(1-cos(2*PI*k/N))/N);222 }223 224 199 // set the phase shifting mode 225 200 void phase_mode(unsigned mode) { 226 201 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; … … 291 266 292 267 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 293 268 // but dont do DC or N/2 component 294 for (unsigned f= 2;f<halfN;f++) {269 for (unsigned f=0;f<halfN;f++) { 295 270 // get left/right amplitudes/phases 296 271 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 297 272 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); … … 306 281 phaseDiff = abs(phaseDiff); 307 282 308 283 if (linear_steering) { 309 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);310 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */311 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();312 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);313 314 /*315 Problem:316 This assumes that the values are interpolated linearly between the cardinal points.317 But this way we have no chance of knowing the average volume...318 - Can we solve that computing everything under the assumption of normalized volume?319 No. Seemingly not.320 - Maybe we should add w explitcitly into the equation and see if we can solve it...321 */322 323 324 //cfloat lt(0.5,0),rt(0.5,0);325 //cfloat x(0,0), y(1,0);326 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);327 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);328 cfloat s = sqrt(p*p/4.0f - q);329 cfloat x = -p;330 cfloat x1 = -p/2.0f + s;331 cfloat x2 = -p/2.0f - s;332 float x = 0;333 if (x1.real() >= -1 && x1.real() <= 1)334 x = x1.real();335 else if (x2.real() >= -1 && x2.real() <= 1)336 x = x2.real();*/337 338 //cfloat yp = (rt - (x*E+H))/(F+x*G);339 //cfloat xp = (lt - (y*B+D))/(A+y*C);340 341 /*xfs[f] = x;342 yfs[f] = y.real();*/343 344 284 // --- this is the fancy new linear mode --- 345 285 346 286 // get sound field x/y position … … 598 538 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 599 539 float surround_balance; // the xfs balance that follows from the coeffs 600 540 float surround_level; // gain for the surround channels (follows from the coeffs 601 float master_gain; // gain for all channels602 541 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 603 542 float front_separation; // front stereo separation 604 543 float rear_separation; // rear stereo separation … … 626 565 627 566 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 628 567 629 void fsurround_decoder::gain(float gain) { impl->surround_gain(gain); }630 631 568 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 632 569 633 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 … … 329 324 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 330 325 { 331 326 int16bufs->l[ic] = *samples++ >> 1; 332 int16bufs->c[ic] = *samples++ >> 1;333 327 int16bufs->r[ic] = *samples++ >> 1; 328 int16bufs->c[ic] = *samples++ >> 1; 329 int16bufs->lfe[ic] = *samples++ >> 1; 334 330 int16bufs->ls[ic] = *samples++ >> 1; 335 331 int16bufs->rs[ic] = *samples++ >> 1; 336 int16bufs->lfe[ic] = *samples++ >> 1;337 332 } 338 333 break; 339 334 } … … 391 386 for (i=0;i<numSamples;i++) 392 387 { 393 388 *l++ = *samples++ >> 1; 394 *c++ = *samples++ >> 1;395 389 *r++ = *samples++ >> 1; 390 *c++ = *samples++ >> 1; 391 *lfe++ = *samples++ >> 1; 396 392 *ls++ = *samples++ >> 1; 397 393 *rs++ = *samples++ >> 1; 398 *lfe++ = *samples++ >> 1;399 394 } 400 395 } break; 401 396 } … … 479 474 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 480 475 { 481 476 int16bufs->l[ic] = *samples++ << 7; 482 int16bufs->c[ic] = *samples++ << 7;483 477 int16bufs->r[ic] = *samples++ << 7; 478 int16bufs->c[ic] = *samples++ << 7; 479 int16bufs->lfe[ic] = *samples++ << 7; 484 480 int16bufs->ls[ic] = *samples++ << 7; 485 481 int16bufs->rs[ic] = *samples++ << 7; 486 int16bufs->lfe[ic] = *samples++ << 7;487 482 } 488 483 break; 489 484 } … … 541 536 for (i=0;i<numSamples;i++) 542 537 { 543 538 *l++ = *samples++ << 7; 544 *c++ = *samples++ << 7;545 539 *r++ = *samples++ << 7; 540 *c++ = *samples++ << 7; 541 *lfe++ = *samples++ << 7; 546 542 *ls++ = *samples++ << 7; 547 543 *rs++ = *samples++ << 7; 548 *lfe++ = *samples++ << 7;549 544 } 550 545 } break; 551 546 } … … 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 // 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
121 121 return gc; 122 122 } 123 123 124 static HostComboBox *SRCQuality() 125 { 126 HostComboBox *gc = new HostComboBox("SRCQuality", false); 127 gc->setLabel(QObject::tr("Sample Rate Conversion")); 128 gc->addSelection(QObject::tr("Best"), "3", true); // default 129 gc->addSelection(QObject::tr("Medium"), "2"); 130 gc->addSelection(QObject::tr("Fastest"), "1"); 131 gc->setHelpText( 132 QObject::tr( 133 "Set the quality of audio sample rate conversion. " 134 "This only affects non 48000Hz PCM audio. " 135 "All three options offer a worst-case SNR of 97dB. " 136 "'Best' at a bandwidth of 97%. " 137 "'Medium' at a bandwidth of 90%. " 138 "'Fastest' at a bandwidth of 80%. " 139 ) 140 ); 141 return gc; 142 } 143 144 124 145 static HostComboBox *PassThroughOutputDevice() 125 146 { 126 147 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3524 3545 3525 3546 addChild(MaxAudioChannels()); 3526 3547 addChild(AudioUpmixType()); 3548 addChild(SRCQuality()); 3527 3549 3528 3550 // General boolean settings 3529 3551 addChild(AC3PassThrough()); -
mythtv/programs/mythtranscode/transcode.cpp
49 49 AudioReencodeBuffer(int audio_bits, int audio_channels) 50 50 { 51 51 Reset(); 52 const AudioSettings settings(audio_bits, audio_channels, 0, false);52 const AudioSettings settings(audio_bits, audio_channels, 0, 0, false); 53 53 Reconfigure(settings); 54 54 bufsize = 512000; 55 55 audiobuffer = new unsigned char[bufsize]; … … 222 222 // Do nothing 223 223 return kMuteOff; 224 224 } 225 virtual bool ToggleUpmix(void) 226 { 227 // Do nothing 228 return false; 229 } 225 230 226 231 // These are pure virtual in AudioOutput, but we don't need them here 227 232 virtual void bufferOutputData(bool){ return; }