Ticket #1104: mythtv_ac3.48.patch
File mythtv_ac3.48.patch, 70.7 KB (added by , 16 years ago) |
---|
-
configure
752 752 libfaac 753 753 libfaad 754 754 libfaadbin 755 libfftw3 755 756 libgsm 756 757 libmp3lame 757 758 libnut … … 2886 2887 echo "libfaac enabled ${libfaac-no}" 2887 2888 echo "libfaad enabled ${libfaad-no}" 2888 2889 echo "libfaad dlopened ${libfaadbin-no}" 2890 echo "libfftw3 support ${liba52-no}" 2889 2891 echo "libgsm enabled ${libgsm-no}" 2890 2892 echo "libmp3lame enabled ${libmp3lame-no}" 2891 2893 echo "libnut enabled ${libnut-no}" -
libs/libs.pro
6 6 # Directories 7 7 SUBDIRS += libavutil libavcodec libavformat libmythsamplerate 8 8 SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav 9 SUBDIRS += libmythfreesurround 9 10 10 11 mingw : SUBDIRS += libmyth libmythupnp libmythui 11 12 !mingw: SUBDIRS += libmythupnp libmythui libmyth -
libs/libmyth/libmyth.pro
11 11 12 12 # Input 13 13 HEADERS += audiooutput.h audiooutputbase.h audiooutputnull.h 14 HEADERS += audiooutputdigitalencoder.h 14 15 HEADERS += backendselect.h dbsettings.h dialogbox.h 15 16 HEADERS += DisplayRes.h DisplayResScreen.h exitcodes.h 16 17 HEADERS += generictree.h httpcomms.h langsettings.h lcddevice.h … … 25 26 HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h 26 27 HEADERS += mythhdd.h mythcdrom.h 27 28 HEADERS += compat.h 29 HEADERS += audiooutputdigitalencoder.h 28 30 29 31 SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp 32 SOURCES += audiooutputdigitalencoder.cpp 30 33 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp 31 34 SOURCES += DisplayRes.cpp DisplayResScreen.cpp 32 35 SOURCES += generictree.cpp httpcomms.cpp langsettings.cpp lcddevice.cpp … … 41 44 SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp 42 45 SOURCES += mythhdd.cpp mythcdrom.cpp 43 46 44 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./ 47 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../libmythfreesurround 48 INCLUDEPATH += ../libavcodec ../libavutil 49 INCLUDEPATH += ../.. ../ ./ 45 50 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 46 DEPENDPATH += ../libmythupnp 51 DEPENDPATH += ../libmythupnp ../libmythfreesurround ../libavcodec ../libavutil 47 52 48 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}49 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}50 LIBS += -L../libmythui -lmythui-$${LIBVERSION}51 LIBS += -L../libmythupnp -lmythupnp-$${LIBVERSION}52 53 54 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 55 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 56 LIBS += -L../libmythui -lmythui-$${LIBVERSION} 57 LIBS += -L../libmythupnp -lmythupnp-$${LIBVERSION} 58 LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION} 59 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 60 LIBS += -L../libavutil -lmythavutil-$${LIBVERSION} 61 53 62 TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT} 54 63 TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT} 64 TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT} 55 65 56 66 # Install headers so that plugins can compile independently 57 67 inc.path = $${PREFIX}/include/mythtv/ … … 221 231 use_hidesyms { 222 232 QMAKE_CXXFLAGS += -fvisibility=hidden 223 233 } 234 235 contains( CONFIG_LIBA52, yes ) { 236 LIBS += -la52 237 } 238 239 contains( CONFIG_LIBFFTW3, yes ) { 240 LIBS += -lfftw3f 241 } -
libs/libmyth/audiooutput.h
31 31 virtual ~AudioOutput() { }; 32 32 33 33 // reconfigure sound out for new params 34 virtual void Reconfigure(int audio_bits, int audio_channels, 35 int audio_samplerate, bool audio_passthru) = 0; 34 virtual void Reconfigure(int audio_bits, 35 int audio_channels, 36 int audio_samplerate, 37 bool audio_passthru, 38 void* audio_codec = NULL) = 0; 36 39 37 40 virtual void SetStretchFactor(float factor); 41 virtual float GetStretchFactor(void) { return 1.0f; } 38 42 39 43 // do AddSamples calls block? 40 44 virtual void SetBlocking(bool blocking) = 0; … … 76 80 lastError = msg; 77 81 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 78 82 } 83 void ClearError(void) { lastError = QString::null; } 79 84 80 85 void Warn(QString msg) 81 86 { -
libs/libmyth/audiooutputdx.h
35 35 /// END HACK HACK HACK HACK 36 36 37 37 virtual void Reset(void); 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, int audio_passthru); 38 virtual void Reconfigure(int audio_bits, 39 int audio_channels, 40 int audio_samplerate, 41 bool audio_passthru, 42 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 40 43 virtual void SetBlocking(bool blocking); 41 44 42 45 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
130 130 // FIXME: kedl: not sure what else could be required here? 131 131 } 132 132 133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 134 int audio_samplerate, int audio_passthru) 133 void AudioOutputDX::Reconfigure(int audio_bits, 134 int audio_channels, 135 int audio_samplerate, 136 int audio_passthru, 137 AudioCodecMode laom) 135 138 { 136 139 if (dsbuffer) 137 140 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
16 16 // MythTV headers 17 17 #include "audiooutput.h" 18 18 #include "samplerate.h" 19 #include "SoundTouch.h"20 19 21 #define AUDBUFSIZE 768000 20 namespace soundtouch { 21 class SoundTouch; 22 }; 23 class FreeSurround; 24 class AudioOutputDigitalEncoder; 25 struct AVCodecContext; 26 22 27 #define AUDIO_SRC_IN_SIZE 16384 23 28 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 29 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 30 31 //#define AUDBUFSIZE 768000 32 //divisible by 12,10,8,6,4,2 and around 1024000 33 //#define AUDBUFSIZE 1024080 34 #define AUDBUFSIZE 1536000 35 26 36 class AudioOutputBase : public AudioOutput 27 37 { 28 38 public: … … 35 45 virtual ~AudioOutputBase(); 36 46 37 47 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, 50 int audio_samplerate, 51 bool audio_passthru, 52 void* audio_codec = NULL); 40 53 41 54 // do AddSamples calls block? 42 55 virtual void SetBlocking(bool blocking); … … 45 58 virtual void SetEffDsp(int dsprate); 46 59 47 60 virtual void SetStretchFactor(float factor); 61 virtual float GetStretchFactor(void); 48 62 49 63 virtual void Reset(void); 50 64 … … 127 141 bool audio_passthru; 128 142 129 143 float audio_stretchfactor; 144 AVCodecContext *audio_codec; 130 145 AudioOutputSource source; 131 146 132 147 bool killaudio; … … 135 150 bool set_initial_vol; 136 151 bool buffer_output_data_for_use; // used by AudioOutputNULL 137 152 153 int configured_audio_channels; 154 138 155 private: 139 156 // resampler 140 157 bool need_resampler; … … 145 162 short tmp_buff[AUDIO_TMP_BUF_SIZE]; 146 163 147 164 // timestretch 148 soundtouch::SoundTouch * pSoundStretch; 165 soundtouch::SoundTouch *pSoundStretch; 166 AudioOutputDigitalEncoder *encoder; 167 FreeSurround *upmixer; 149 168 169 int source_audio_channels; 170 int source_audio_bytes_per_sample; 171 bool needs_upmix; 172 int surround_mode; 173 150 174 bool blocking; // do AddSamples calls block? 151 175 152 176 int lastaudiolen; … … 164 188 165 189 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 166 190 'audiotime' and 'audiotime_updated' */ 167 int audiotime; // timecode of audio leaving the soundcard (same units as168 // timecodes) ...191 /// timecode of audio leaving the soundcard (same units as timecodes) 192 long long audiotime; 169 193 struct timeval audiotime_updated; // ... which was last updated at this time 170 194 171 195 /* Audio circular buffer */ 172 196 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 173 197 int raud, waud; /* read and write positions */ 174 int audbuf_timecode; /* timecode of audio most recently placed into175 buffer */198 /// timecode of audio most recently placed into buffer 199 long long audbuf_timecode; 176 200 177 201 int numlowbuffer; 178 202 -
libs/libmyth/audiooutputbase.cpp
15 15 16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 #include "audiooutputdigitalencoder.h" 19 #include "SoundTouch.h" 20 #include "freesurround.h" 18 21 #include "compat.h" 19 22 20 23 #define LOC QString("AO: ") … … 36 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 37 40 audio_passthru(false), audio_stretchfactor(1.0f), 38 41 42 audio_codec(NULL), 39 43 source(lsource), killaudio(false), 40 44 41 45 pauseaudio(false), audio_actually_paused(false), … … 47 51 48 52 src_ctx(NULL), 49 53 50 pSoundStretch(NULL), blocking(false), 54 pSoundStretch(NULL), 55 encoder(NULL), 56 upmixer(NULL), 57 source_audio_channels(-1), 58 source_audio_bytes_per_sample(0), 59 needs_upmix(false), 60 surround_mode(FreeSurround::SurroundModePassive), 51 61 62 blocking(false), 63 52 64 lastaudiolen(0), samples_buffered(0), 53 65 54 66 audio_thread_exists(false), … … 71 83 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 84 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 85 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 86 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 87 75 88 // You need to call Reconfigure from your concrete class. 76 89 // Reconfigure(laudio_bits, laudio_channels, … … 111 124 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 125 .arg(audio_stretchfactor)); 113 126 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 127 if (audio_codec) 128 { 129 if (!encoder) 130 { 131 VERBOSE(VB_AUDIO, LOC + 132 QString("Creating Encoder for codec %1 origfs %2") 133 .arg(audio_codec->codec_id) 134 .arg(audio_codec->frame_size)); 116 135 136 encoder = new AudioOutputDigitalEncoder(); 137 if (!encoder->Init(audio_codec->codec_id, 138 audio_codec->bit_rate, 139 audio_codec->sample_rate, 140 audio_codec->channels 141 )) 142 { 143 // eeks 144 delete encoder; 145 encoder = NULL; 146 VERBOSE(VB_AUDIO, LOC + 147 QString("Failed to Create Encoder")); 148 } 149 } 150 } 151 if (encoder) 152 { 153 pSoundStretch->setSampleRate(audio_codec->sample_rate); 154 pSoundStretch->setChannels(audio_codec->channels); 155 } 156 else 157 { 158 pSoundStretch->setSampleRate(audio_samplerate); 159 pSoundStretch->setChannels(audio_channels); 160 } 161 117 162 pSoundStretch->setTempo(audio_stretchfactor); 118 163 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); 119 164 … … 134 179 pthread_mutex_unlock(&audio_buflock); 135 180 } 136 181 182 float AudioOutputBase::GetStretchFactor() 183 { 184 return audio_stretchfactor; 185 } 186 137 187 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 188 int laudio_samplerate, bool laudio_passthru, 189 void* laudio_codec) 139 190 { 140 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 191 int codec_id = CODEC_ID_NONE; 192 int lcodec_id = CODEC_ID_NONE; 193 int lcchannels = 0; 194 int cchannels = 0; 195 int lsource_audio_channels = laudio_channels; 196 bool lneeds_upmix = false; 197 198 if (laudio_codec) 199 { 200 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 201 laudio_bits = 16; 202 laudio_channels = 2; 203 lsource_audio_channels = laudio_channels; 204 laudio_samplerate = 48000; 205 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 206 } 207 208 if (audio_codec) 209 { 210 codec_id = audio_codec->codec_id; 211 cchannels = ((AVCodecContext*)audio_codec)->channels; 212 } 213 214 if ((configured_audio_channels == 6) && 215 !(laudio_codec || audio_codec)) 216 { 217 laudio_channels = configured_audio_channels; 218 lneeds_upmix = true; 219 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 220 } 221 222 ClearError(); 223 bool general_deps = (laudio_bits == audio_bits && 224 laudio_channels == audio_channels && 225 laudio_samplerate == audio_samplerate && !need_resampler && 226 laudio_passthru == audio_passthru && 227 lneeds_upmix == needs_upmix && 228 lcodec_id == codec_id && lcchannels == cchannels); 229 bool upmix_deps = 230 (lsource_audio_channels == source_audio_channels); 231 if (general_deps && upmix_deps) 232 { 233 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 234 return; 235 } 144 236 237 if (general_deps && !upmix_deps && lneeds_upmix && upmixer) 238 { 239 upmixer->flush(); 240 source_audio_channels = lsource_audio_channels; 241 VERBOSE(VB_AUDIO,LOC + QString("source channels changed to %1").arg(source_audio_channels)); 242 return; 243 } 244 145 245 KillAudio(); 146 246 147 247 pthread_mutex_lock(&audio_buflock); … … 151 251 waud = raud = 0; 152 252 audio_actually_paused = false; 153 253 254 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 255 audio_channels = laudio_channels; 256 source_audio_channels = lsource_audio_channels; 155 257 audio_bits = laudio_bits; 156 258 audio_samplerate = laudio_samplerate; 259 audio_codec = (AVCodecContext*)laudio_codec; 157 260 audio_passthru = laudio_passthru; 261 needs_upmix = lneeds_upmix; 262 158 263 if (audio_bits != 8 && audio_bits != 16) 159 264 { 160 265 pthread_mutex_unlock(&avsync_lock); … … 162 267 Error("AudioOutput only supports 8 or 16bit audio."); 163 268 return; 164 269 } 270 165 271 audio_bytes_per_sample = audio_channels * audio_bits / 8; 272 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 166 273 167 274 need_resampler = false; 168 275 killaudio = false; … … 172 279 173 280 numlowbuffer = 0; 174 281 282 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 283 .arg(audio_main_device).arg(audio_channels) 284 .arg(source_audio_channels).arg(audio_samplerate)); 285 175 286 // Actually do the device specific open call 176 287 if (!OpenDevice()) 177 288 { 178 289 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 290 pthread_mutex_unlock(&avsync_lock); 180 291 pthread_mutex_unlock(&audio_buflock); 292 if (GetError().isEmpty()) 293 Error("Aborting reconfigure"); 294 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 295 return; 182 296 } 183 297 … … 200 314 current_seconds = -1; 201 315 source_bitrate = -1; 202 316 317 // NOTE: this won't do anything as above samplerate vars are set equal 203 318 // Check if we need the resampler 204 319 if (audio_samplerate != laudio_samplerate) 205 320 { … … 222 337 need_resampler = true; 223 338 } 224 339 340 if (needs_upmix) 341 { 342 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 343 if (configured_audio_channels == 6) 344 { 345 surround_mode = gContext->GetNumSetting("AudioUpmixType", 2); 346 } 347 348 upmixer = new FreeSurround( 349 audio_samplerate, 350 source == AUDIOOUTPUT_VIDEO, 351 (FreeSurround::SurroundMode)surround_mode); 352 353 VERBOSE(VB_AUDIO, LOC + 354 QString("create upmixer done with surround mode %1") 355 .arg(surround_mode)); 356 } 357 225 358 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 359 .arg(audio_stretchfactor)); 360 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 361 .arg((audio_codec) ? 362 codec_id_string(audio_codec->codec_id) : "not set")); 227 363 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 364 if (redo_stretch) 230 365 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 366 float laudio_stretchfactor = audio_stretchfactor; 367 delete pSoundStretch; 368 pSoundStretch = NULL; 369 audio_stretchfactor = 0.0f; 370 SetStretchFactorLocked(laudio_stretchfactor); 233 371 } 372 else 373 { 374 SetStretchFactorLocked(audio_stretchfactor); 375 if (pSoundStretch) 376 { 377 // if its passthru then we need to reencode 378 if (audio_codec) 379 { 380 if (!encoder) 381 { 382 VERBOSE(VB_AUDIO, LOC + 383 QString("Creating Encoder for codec %1") 384 .arg(audio_codec->codec_id)); 234 385 386 encoder = new AudioOutputDigitalEncoder(); 387 if (!encoder->Init(audio_codec->codec_id, 388 audio_codec->bit_rate, 389 audio_codec->sample_rate, 390 audio_codec->channels 391 )) 392 { 393 // eeks 394 delete encoder; 395 encoder = NULL; 396 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 397 } 398 } 399 } 400 if (encoder) 401 { 402 pSoundStretch->setSampleRate(audio_codec->sample_rate); 403 pSoundStretch->setChannels(audio_codec->channels); 404 } 405 else 406 { 407 pSoundStretch->setSampleRate(audio_samplerate); 408 pSoundStretch->setChannels(audio_channels); 409 } 410 } 411 } 412 235 413 // Setup visualisations, zero the visualisations buffers 236 414 prepareVisuals(); 237 415 … … 290 468 pSoundStretch = NULL; 291 469 } 292 470 471 if (encoder) 472 { 473 delete encoder; 474 encoder = NULL; 475 } 476 477 if (upmixer) 478 { 479 delete upmixer; 480 upmixer = NULL; 481 } 482 needs_upmix = false; 483 293 484 CloseDevice(); 294 485 295 486 killAudioLock.unlock(); … … 303 494 304 495 void AudioOutputBase::Pause(bool paused) 305 496 { 497 VERBOSE(VB_AUDIO, LOC + QString("Pause %0").arg(paused)); 306 498 pauseaudio = paused; 307 499 audio_actually_paused = false; 308 500 } … … 385 577 The reason is that computing 'audiotime' requires acquiring the audio 386 578 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 579 from the audio thread, and then call this from the video thread. */ 388 intret;580 long long ret; 389 581 struct timeval now; 390 582 391 583 if (audiotime == 0) … … 397 589 398 590 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 591 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);592 ret = (long long)(ret * audio_stretchfactor); 401 593 594 #if 1 595 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 596 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 597 .arg(now.tv_sec).arg(now.tv_usec) 598 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 599 .arg(ret) 600 .arg(audiotime) 601 .arg(audio_stretchfactor) 602 ); 603 #endif 604 402 605 ret += audiotime; 403 606 404 607 pthread_mutex_unlock(&avsync_lock); 405 return ret;608 return (int)ret; 406 609 } 407 610 408 611 void AudioOutputBase::SetAudiotime(void) … … 439 642 // include algorithmic latencies 440 643 if (pSoundStretch) 441 644 { 645 // add the effect of any unused but processed samples, 646 // AC3 reencode does this 647 totalbuffer += (int)(pSoundStretch->numSamples() * 648 audio_bytes_per_sample); 442 649 // add the effect of unprocessed samples in time stretch algo 443 650 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 651 audio_bytes_per_sample) / audio_stretchfactor); 445 652 } 446 653 654 if (upmixer && needs_upmix) 655 { 656 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 657 } 658 447 659 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 660 (audio_bytes_per_sample * effdspstretched)); 449 661 450 662 gettimeofday(&audiotime_updated, NULL); 663 #if 1 664 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 665 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 666 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 667 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 668 .arg(audiotime) 669 .arg(audbuf_timecode) 670 .arg(totalbuffer) 671 .arg(soundcard_buffer) 672 .arg(effdspstretched) 673 .arg(audio_bytes_per_sample) 674 .arg(audio_stretchfactor) 675 ); 676 #endif 451 677 452 678 pthread_mutex_unlock(&avsync_lock); 453 679 pthread_mutex_unlock(&audio_buflock); … … 458 684 { 459 685 // NOTE: This function is not threadsafe 460 686 int afree = audiofree(true); 461 int abps = audio_bytes_per_sample; 687 int abps = (encoder) ? 688 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 462 689 int len = samples * abps; 463 690 464 691 // Check we have enough space to write the data 465 692 if (need_resampler && src_ctx) 466 693 len = (int)ceilf(float(len) * src_data.src_ratio); 467 694 695 // include samples in upmix buffer that may be flushed 696 if (needs_upmix && upmixer) 697 len += upmixer->numUnprocessedSamples() * abps; 698 468 699 if (pSoundStretch) 469 700 len += (pSoundStretch->numUnprocessedSamples() + 470 701 (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps; … … 520 751 // NOTE: This function is not threadsafe 521 752 522 753 int afree = audiofree(true); 523 int abps = audio_bytes_per_sample; 754 int abps = (encoder) ? 755 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 524 756 int len = samples * abps; 525 757 526 758 // Check we have enough space to write the data 527 759 if (need_resampler && src_ctx) 528 760 len = (int)ceilf(float(len) * src_data.src_ratio); 529 761 762 // include samples in upmix buffer that may be flushed 763 if (needs_upmix && upmixer) 764 len += upmixer->numUnprocessedSamples() * abps; 765 530 766 if (pSoundStretch) 531 767 { 532 768 len += (pSoundStretch->numUnprocessedSamples() + … … 575 811 576 812 int AudioOutputBase::WaitForFreeSpace(int samples) 577 813 { 578 int len = samples * audio_bytes_per_sample; 814 int abps = (encoder) ? 815 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 816 int len = samples * abps; 579 817 int afree = audiofree(false); 580 818 581 819 while (len > afree) 582 820 { 583 821 if (blocking) 584 822 { 585 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +823 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 586 824 QString("(need %1, available %2)").arg(len).arg(afree)); 587 825 588 826 // wait for more space … … 591 829 } 592 830 else 593 831 { 594 VERBOSE(VB_IMPORTANT, LOC_ERR + 595 "Audio buffer overflow, audio data lost!"); 596 samples = afree / audio_bytes_per_sample; 597 len = samples * audio_bytes_per_sample; 832 VERBOSE(VB_IMPORTANT, LOC_ERR + 833 QString("Audio buffer overflow, %1 audio samples lost!") 834 .arg(samples - (afree / abps))); 835 samples = afree / abps; 836 len = samples * abps; 598 837 if (src_ctx) 599 838 { 600 839 int error = src_reset(src_ctx); … … 619 858 620 859 int afree = audiofree(false); 621 860 622 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 623 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 624 .arg(samples * audio_bytes_per_sample) 625 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 861 int abps = (encoder) ? 862 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 863 864 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 865 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, " 866 "free=%4, timecode=%5 needsupmix %6") 867 .arg(samples) 868 .arg(samples * abps) 869 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 870 .arg(needs_upmix)); 626 871 627 len = WaitForFreeSpace(samples); 628 629 if (interleaved) 872 if (upmixer && needs_upmix) 630 873 { 631 char *mybuf = (char*)buffer; 632 int bdiff = AUDBUFSIZE - org_waud; 633 if (bdiff < len) 874 int out_samples = 0; 875 int step = (interleaved)?source_audio_channels:1; 876 len = WaitForFreeSpace(samples); // test 877 for (int itemp = 0; itemp < samples; ) 634 878 { 635 memcpy(audiobuffer + org_waud, mybuf, bdiff); 636 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 879 // just in case it does a processing cycle, release the lock 880 // to allow the output loop to do output 881 pthread_mutex_unlock(&audio_buflock); 882 if (audio_bytes == 2) 883 { 884 itemp += upmixer->putSamples( 885 (short*)buffer + itemp * step, 886 samples - itemp, 887 source_audio_channels, 888 (interleaved) ? 0 : samples); 889 } 890 else 891 { 892 itemp += upmixer->putSamples( 893 (char*)buffer + itemp * step, 894 samples - itemp, 895 source_audio_channels, 896 (interleaved) ? 0 : samples); 897 } 898 pthread_mutex_lock(&audio_buflock); 899 900 int copy_samples = upmixer->numSamples(); 901 if (copy_samples) 902 { 903 int copy_len = copy_samples * abps; 904 out_samples += copy_samples; 905 if (out_samples > samples) 906 len = WaitForFreeSpace(out_samples); 907 int bdiff = AUDBUFSIZE - org_waud; 908 if (bdiff < copy_len) 909 { 910 int bdiff_samples = bdiff/abps; 911 upmixer->receiveSamples( 912 (short*)(audiobuffer + org_waud), bdiff_samples); 913 upmixer->receiveSamples( 914 (short*)(audiobuffer), (copy_samples - bdiff_samples)); 915 } 916 else 917 { 918 upmixer->receiveSamples( 919 (short*)(audiobuffer + org_waud), copy_samples); 920 } 921 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 922 } 637 923 } 638 else 639 memcpy(audiobuffer + org_waud, mybuf, len); 640 641 org_waud = (org_waud + len) % AUDBUFSIZE; 642 } 643 else 924 925 if (samples > 0) 926 len = WaitForFreeSpace(out_samples); 927 928 samples = out_samples; 929 } 930 else 644 931 { 645 char **mybuf = (char**)buffer; 646 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 932 len = WaitForFreeSpace(samples); 933 934 if (interleaved) 647 935 { 648 for (int chan = 0; chan < audio_channels; chan++) 936 char *mybuf = (char*)buffer; 937 int bdiff = AUDBUFSIZE - org_waud; 938 if (bdiff < len) 649 939 { 650 audiobuffer[org_waud++] = mybuf[chan][itemp]; 651 if (audio_bits == 16) 652 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 940 memcpy(audiobuffer + org_waud, mybuf, bdiff); 941 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 942 } 943 else 944 { 945 memcpy(audiobuffer + org_waud, mybuf, len); 946 } 947 948 org_waud = (org_waud + len) % AUDBUFSIZE; 949 } 950 else 951 { 952 char **mybuf = (char**)buffer; 953 for (int itemp = 0; itemp < samples * audio_bytes; 954 itemp += audio_bytes) 955 { 956 for (int chan = 0; chan < audio_channels; chan++) 957 { 958 audiobuffer[org_waud++] = mybuf[chan][itemp]; 959 if (audio_bits == 16) 960 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 653 961 654 if (org_waud >= AUDBUFSIZE) 655 org_waud -= AUDBUFSIZE; 962 if (org_waud >= AUDBUFSIZE) 963 org_waud -= AUDBUFSIZE; 964 } 656 965 } 657 966 } 658 967 } 659 968 660 if ( pSoundStretch)969 if (samples > 0) 661 970 { 662 // does not change the timecode, only the number of samples 663 // back to orig pos 664 org_waud = waud; 665 int bdiff = AUDBUFSIZE - org_waud; 666 int nSamplesToEnd = bdiff/audio_bytes_per_sample; 667 if (bdiff < len) 971 if (pSoundStretch) 668 972 { 669 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +670 org_waud), nSamplesToEnd);671 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,672 (len - bdiff) / audio_bytes_per_sample);673 }674 else675 {676 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +677 org_waud), len / audio_bytes_per_sample);678 }679 973 680 int newLen = 0; 681 int nSamples; 682 len = WaitForFreeSpace(pSoundStretch->numSamples() * 683 audio_bytes_per_sample); 684 do 685 { 686 int samplesToGet = len/audio_bytes_per_sample; 687 if (samplesToGet > nSamplesToEnd) 974 // does not change the timecode, only the number of samples 975 // back to orig pos 976 org_waud = waud; 977 int bdiff = AUDBUFSIZE - org_waud; 978 int nSamplesToEnd = bdiff/abps; 979 if (bdiff < len) 688 980 { 689 samplesToGet = nSamplesToEnd; 981 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 982 (audiobuffer + 983 org_waud), nSamplesToEnd); 984 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 985 (len - bdiff) / abps); 690 986 } 987 else 988 { 989 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 990 (audiobuffer + org_waud), 991 len / abps); 992 } 691 993 692 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 693 (audiobuffer + org_waud), samplesToGet); 694 if (nSamples == nSamplesToEnd) 994 if (encoder) 695 995 { 696 org_waud = 0; 697 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 996 // pull out a packet's worth and reencode it until we 997 // don't have enough for any more packets 998 soundtouch::SAMPLETYPE *temp_buff = 999 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1000 size_t frameSize = encoder->FrameSize()/abps; 1001 1002 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1003 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1004 .arg(frameSize) 1005 .arg(encoder->FrameSize()) 1006 .arg(pSoundStretch->numSamples())); 1007 1008 // process the same number of samples as it creates 1009 // a full encoded buffer just like before 1010 while (pSoundStretch->numSamples() >= frameSize) 1011 { 1012 int got = pSoundStretch->receiveSamples( 1013 temp_buff, frameSize); 1014 int amount = encoder->Encode(temp_buff); 1015 1016 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1017 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1018 .arg(amount) 1019 .arg(got) 1020 .arg(pSoundStretch->numSamples())); 1021 1022 if (!amount) 1023 continue; 1024 1025 //len = WaitForFreeSpace(amount); 1026 char *ob = encoder->GetOutBuff(); 1027 if (amount >= bdiff) 1028 { 1029 memcpy(audiobuffer + org_waud, ob, bdiff); 1030 ob += bdiff; 1031 amount -= bdiff; 1032 org_waud = 0; 1033 } 1034 if (amount > 0) 1035 memcpy(audiobuffer + org_waud, ob, amount); 1036 1037 bdiff = AUDBUFSIZE - amount; 1038 org_waud += amount; 1039 } 698 1040 } 699 1041 else 700 1042 { 701 org_waud += nSamples * audio_bytes_per_sample; 702 nSamplesToEnd -= nSamples; 1043 int newLen = 0; 1044 int nSamples; 1045 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1046 audio_bytes_per_sample); 1047 do 1048 { 1049 int samplesToGet = len/audio_bytes_per_sample; 1050 if (samplesToGet > nSamplesToEnd) 1051 { 1052 samplesToGet = nSamplesToEnd; 1053 } 1054 1055 nSamples = pSoundStretch->receiveSamples( 1056 (soundtouch::SAMPLETYPE*) 1057 (audiobuffer + org_waud), samplesToGet); 1058 if (nSamples == nSamplesToEnd) 1059 { 1060 org_waud = 0; 1061 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1062 } 1063 else 1064 { 1065 org_waud += nSamples * audio_bytes_per_sample; 1066 nSamplesToEnd -= nSamples; 1067 } 1068 1069 newLen += nSamples * audio_bytes_per_sample; 1070 len -= nSamples * audio_bytes_per_sample; 1071 } while (nSamples > 0); 703 1072 } 1073 } 704 1074 705 newLen += nSamples * audio_bytes_per_sample; 706 len -= nSamples * audio_bytes_per_sample; 707 } while (nSamples > 0); 708 } 1075 waud = org_waud; 1076 lastaudiolen = audiolen(false); 709 1077 710 waud = org_waud; 711 lastaudiolen = audiolen(false); 1078 if (timecode < 0) 1079 { 1080 // mythmusic doesn't give timestamps.. 1081 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1082 } 1083 1084 samples_buffered += samples; 1085 1086 /* we want the time at the end -- but the file format stores 1087 time at the start of the chunk. */ 1088 // even with timestretch, timecode is still calculated from original 1089 // sample count 1090 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 712 1091 713 samples_buffered += samples; 714 715 if (timecode < 0) 716 { 717 // mythmusic doesn't give timestamps.. 718 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1092 if (interleaved) 1093 { 1094 dispatchVisual((unsigned char *)buffer, len, timecode, 1095 source_audio_channels, audio_bits); 1096 } 719 1097 } 720 721 /* we want the time at the end -- but the file format stores722 time at the start of the chunk. */723 // even with timestretch, timecode is still calculated from original724 // sample count725 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);726 1098 727 if (interleaved)728 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);729 730 1099 pthread_mutex_unlock(&audio_buflock); 731 1100 } 732 1101 … … 739 1108 740 1109 if (source_bitrate == -1) 741 1110 { 742 source_bitrate = audio_samplerate * audio_channels * audio_bits;1111 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 743 1112 } 744 1113 745 1114 if (ct / 1000 != current_seconds) … … 747 1116 current_seconds = ct / 1000; 748 1117 OutputEvent e(current_seconds, ct, 749 1118 source_bitrate, audio_samplerate, audio_bits, 750 audio_channels);1119 source_audio_channels); 751 1120 dispatch(e); 752 1121 } 753 1122 } … … 785 1154 786 1155 space_on_soundcard = getSpaceOnSoundcard(); 787 1156 788 if (space_on_soundcard != last_space_on_soundcard) { 789 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard") 1157 if (space_on_soundcard != last_space_on_soundcard) 1158 { 1159 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1160 LOC + QString("%1 bytes free on soundcard") 790 1161 .arg(space_on_soundcard)); 1162 791 1163 last_space_on_soundcard = space_on_soundcard; 792 1164 } 793 1165 … … 799 1171 WriteAudio(zeros, fragment_size); 800 1172 } else { 801 1173 // this should never happen now -dag 802 VERBOSE(VB_AUDIO , LOC +1174 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 803 1175 QString("waiting for space on soundcard " 804 1176 "to write zeros: have %1 need %2") 805 1177 .arg(space_on_soundcard).arg(fragment_size)); … … 835 1207 if (fragment_size > audiolen(true)) 836 1208 { 837 1209 if (audiolen(true) > 0) // only log if we're sending some audio 838 VERBOSE(VB_AUDIO , LOC +1210 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 839 1211 QString("audio waiting for buffer to fill: " 840 1212 "have %1 want %2") 841 1213 .arg(audiolen(true)).arg(fragment_size)); 842 1214 843 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail"); 1215 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1216 //LOC + "Broadcasting free space avail"); 844 1217 pthread_mutex_lock(&audio_buflock); 845 1218 pthread_cond_broadcast(&audio_bufsig); 846 1219 pthread_mutex_unlock(&audio_buflock); … … 854 1227 if (fragment_size > space_on_soundcard) 855 1228 { 856 1229 if (space_on_soundcard != last_space_on_soundcard) { 857 VERBOSE(VB_AUDIO , LOC +1230 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 858 1231 QString("audio waiting for space on soundcard: " 859 1232 "have %1 need %2") 860 1233 .arg(space_on_soundcard).arg(fragment_size)); … … 916 1289 917 1290 /* update raud */ 918 1291 raud = (raud + fragment_size) % AUDBUFSIZE; 919 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1292 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 920 1293 pthread_cond_broadcast(&audio_bufsig); 921 1294 922 1295 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
89 89 } 90 90 else 91 91 { 92 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 93 buffer_time = 500000; // .5 seconds 92 fragment_size = 93 (audio_bits * audio_channels * audio_samplerate) / (8*30); 94 buffer_time = 100000; 94 95 period_time = buffer_time / 4; // 4 interrupts per buffer 95 96 } 96 97 … … 162 163 163 164 tmpbuf = aubuf; 164 165 165 VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 167 QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 168 .arg(size).arg(frames)); 167 169 168 170 while (frames > 0) -
libs/libmythfreesurround/el_processor.cpp
20 20 #include <complex> 21 21 #include <cmath> 22 22 #include <vector> 23 #ifdef USE_FFTW3 23 24 #include "fftw3.h" 25 #else 26 extern "C" { 27 #include "dsputil.h" 28 }; 29 typedef FFTSample FFTComplexArray[2]; 30 #endif 24 31 25 32 #define FILTERED_LFE 26 33 34 #ifdef USE_FFTW3 27 35 #pragma comment (lib,"libfftw3f-3.lib") 36 #endif 28 37 29 38 typedef std::complex<float> cfloat; 30 39 … … 45 54 // create an instance of the decoder 46 55 // blocksize is fixed over the lifetime of this object for performance reasons 47 56 decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) { 57 #ifdef USE_FFTW3 48 58 // create FFTW buffers 49 59 lt = (float*)fftwf_malloc(sizeof(float)*N); 50 60 rt = (float*)fftwf_malloc(sizeof(float)*N); … … 55 65 loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE); 56 66 loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE); 57 67 store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE); 68 #else 69 // create lavc fft buffers 70 lt = (float*)malloc(sizeof(FFTSample)*N); 71 rt = (float*)malloc(sizeof(FFTSample)*N); 72 dst = (float*)malloc(sizeof(FFTSample)*N); 73 dftL = (FFTComplexArray*)malloc(sizeof(FFTComplex)*N); 74 dftR = (FFTComplexArray*)malloc(sizeof(FFTComplex)*N); 75 src = (FFTComplexArray*)malloc(sizeof(FFTComplex)*N); 76 fftContextForward = (FFTContext*)malloc(sizeof(FFTContext)); 77 memset(fftContextForward, 0, sizeof(FFTContext)); 78 fftContextReverse = (FFTContext*)malloc(sizeof(FFTContext)); 79 memset(fftContextReverse, 0, sizeof(FFTContext)); 80 ff_fft_init(fftContextForward, 13, 0); 81 ff_fft_init(fftContextReverse, 13, 1); 82 #endif 58 83 // resize our own buffers 59 84 frontR.resize(N); 60 85 frontL.resize(N); … … 97 122 98 123 // destructor 99 124 ~decoder_impl() { 125 #ifdef USE_FFTW3 100 126 // clean up the FFTW stuff 101 127 fftwf_destroy_plan(store); 102 128 fftwf_destroy_plan(loadR); … … 107 133 fftwf_free(dst); 108 134 fftwf_free(rt); 109 135 fftwf_free(lt); 136 #else 137 ff_fft_end(fftContextForward); 138 ff_fft_end(fftContextReverse); 139 free(src); 140 free(dftR); 141 free(dftL); 142 free(dst); 143 free(rt); 144 free(lt); 145 free(fftContextForward); 146 free(fftContextReverse); 147 #endif 110 148 } 111 149 112 150 float ** getInputBuffers() … … 237 275 } 238 276 } 239 277 278 #ifdef USE_FFTW3 240 279 // ... and tranform it into the frequency domain 241 280 fftwf_execute(loadL); 242 281 fftwf_execute(loadR); 282 #else 283 ff_fft_permuteRC(fftContextForward, <[0], (FFTComplex*)&dftL[0]); 284 ff_fft_calc(fftContextForward, (FFTComplex*)&dftL[0]); 285 ff_fft_permuteRC(fftContextForward, &rt[0], (FFTComplex*)&dftR[0]); 286 ff_fft_calc(fftContextForward, (FFTComplex*)&dftR[0]); 287 #endif 243 288 244 289 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 245 290 // but dont do DC or N/2 component … … 447 492 // filter the complex source signal and add it to target 448 493 void apply_filter(cfloat *signal, float *flt, float *target) { 449 494 // filter the signal 450 for (unsigned f=0;f<=halfN;f++) { 495 unsigned f; 496 for (f=0;f<=halfN;f++) { 451 497 src[f][0] = signal[f].real() * flt[f]; 452 498 src[f][1] = signal[f].imag() * flt[f]; 453 499 } 500 #ifdef USE_FFTW3 454 501 // transform into time domain 455 502 fftwf_execute(store); 503 #else 504 // enforce odd symmetry 505 for (f=1;f<halfN-1;f++) { 506 src[N-f][0] = src[f][0]; 507 src[N-f][1] = -src[f][1]; // complex conjugate 508 } 509 ff_fft_calc(fftContextReverse, (FFTComplex*)&src[0]); 510 ff_fft_permuteCR(fftContextReverse, (FFTComplex*)&src[0], &dst[0]); 511 #endif 456 512 457 513 float* pT1 = &target[current_buf*halfN]; 458 514 float* pWnd1 = &wnd[0]; … … 470 526 } 471 527 } 472 528 529 #ifndef USE_FFTW3 530 /** 531 * * Do the permutation needed BEFORE calling ff_fft_calc() 532 * special for freesurround that also copies 533 * */ 534 void ff_fft_permuteRC(FFTContext *s, FFTSample *r, FFTComplex *z) 535 { 536 int j, k, np; 537 FFTComplex tmp; 538 const uint16_t *revtab = s->revtab; 539 540 /* reverse */ 541 np = 1 << s->nbits; 542 for(j=0;j<np;j++) { 543 k = revtab[j]; 544 if (k < j) { 545 z[k].re = r[j]; 546 z[k].im = 0.0; 547 z[j].re = r[k]; 548 z[j].im = 0.0; 549 } 550 } 551 } 552 553 /** 554 * * Do the permutation needed BEFORE calling ff_fft_calc() 555 * special for freesurround that also copies and 556 * discards im component as it should be 0 557 * */ 558 void ff_fft_permuteCR(FFTContext *s, FFTComplex *z, FFTSample *r) 559 { 560 int j, k, np; 561 FFTComplex tmp; 562 const uint16_t *revtab = s->revtab; 563 564 /* reverse */ 565 np = 1 << s->nbits; 566 for(j=0;j<np;j++) { 567 k = revtab[j]; 568 if (k < j) { 569 r[k] = z[j].re; 570 r[j] = z[k].re; 571 } 572 } 573 } 574 #endif 575 473 576 unsigned int N; // the block size 474 577 unsigned int halfN; // half block size precalculated 578 #ifdef USE_FFTW3 475 579 // FFTW data structures 476 580 float *lt,*rt,*dst; // left total, right total (source arrays), destination array 477 581 fftwf_complex *dftL,*dftR,*src; // intermediate arrays (FFTs of lt & rt, processing source) 478 582 fftwf_plan loadL,loadR,store; // plans for loading the data into the intermediate format and back 583 #else 584 FFTContext *fftContextForward, *fftContextReverse; 585 FFTSample *lt,*rt,*dst; // left total, right total (source arrays), destination array 586 FFTComplexArray *dftL,*dftR,*src; // intermediate arrays (FFTs of lt & rt, processing source) 587 #endif 479 588 // buffers 480 589 std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain 481 590 #ifdef FILTERED_LFE -
libs/libmythfreesurround/libmythfreesurround.pro
19 19 SOURCES += el_processor.cpp 20 20 SOURCES += freesurround.cpp 21 21 22 #required until its rewritten to use avcodec fft lib 23 #LIBS += -lfftw3 24 LIBS += -lfftw3f 25 22 contains( CONFIG_LIBFFTW3, yes ) { 23 #required until its rewritten to use avcodec fft lib 24 LIBS += -lfftw3f 25 DEFINES += USE_FFTW3 26 } else { 27 #required until its rewritten to use avcodec fft lib 28 DEPENDPATH += ../libavcodec 29 LIBS += -L../libavcodec -lavcodec 30 INCLUDEPATH += ../../libs/libavutil 31 } -
programs/mythfrontend/globalsettings.cpp
56 56 } 57 57 #endif 58 58 #ifdef USING_ALSA 59 gc->addSelection("ALSA:default", "ALSA:default"); 59 gc->addSelection("ALSA:default", "ALSA:default"); 60 gc->addSelection("ALSA:surround51", "ALSA:surround51"); 61 gc->addSelection("ALSA:analog", "ALSA:analog"); 62 gc->addSelection("ALSA:digital", "ALSA:digital"); 63 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 64 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 60 65 #endif 61 66 #ifdef USING_ARTS 62 67 gc->addSelection("ARTS:", "ARTS:"); … … 78 83 return gc; 79 84 } 80 85 86 static HostComboBox *MaxAudioChannels() 87 { 88 HostComboBox *gc = new HostComboBox("MaxChannels",false); 89 gc->setLabel(QObject::tr("Max Audio Channels")); 90 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 91 gc->addSelection(QObject::tr("5.1"), "6"); 92 gc->setHelpText( 93 QObject::tr( 94 "Set the maximum number of audio channels to be decoded. " 95 "This is for multi-channel/surround audio playback.")); 96 return gc; 97 } 98 99 static HostComboBox *AudioUpmixType() 100 { 101 HostComboBox *gc = new HostComboBox("AudioUpmixType",false); 102 gc->setLabel(QObject::tr("Upmix")); 103 gc->addSelection(QObject::tr("Passive"), "0"); 104 gc->addSelection(QObject::tr("Active Simple"), "1"); 105 gc->addSelection(QObject::tr("Active Linear"), "2", true); // default 106 gc->setHelpText( 107 QObject::tr( 108 "Set the audio upmix type for 2ch to 6ch conversion. " 109 "This is for multi-channel/surround audio playback.")); 110 return gc; 111 } 112 81 113 static HostComboBox *PassThroughOutputDevice() 82 114 { 83 115 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3202 3234 vgrp0->addChild(AC3PassThrough()); 3203 3235 vgrp0->addChild(DTSPassThrough()); 3204 3236 3237 HorizontalConfigurationGroup *agrp = 3238 new HorizontalConfigurationGroup(false, false, true, true); 3239 agrp->addChild(MaxAudioChannels()); 3240 agrp->addChild(AudioUpmixType()); 3241 addChild(agrp); 3242 3205 3243 VerticalConfigurationGroup *vgrp1 = 3206 3244 new VerticalConfigurationGroup(false, false, true, true); 3207 3245 vgrp1->addChild(AggressiveBuffer()); -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 virtual void Reconfigure(int audio_bits, int audio_channels, 58 int audio_samplerate, bool audio_passthru) 58 int audio_samplerate, bool audio_passthru, 59 void *audio_codec = NULL) 59 60 { 61 ClearError(); 60 62 (void)audio_samplerate; 61 63 (void)audio_passthru; 64 (void)audio_codec; 62 65 bits = audio_bits; 63 66 channels = audio_channels; 64 67 bytes_per_sample = bits * channels / 8; 68 if ((uint)audio_channels > 2) 69 Error(QString("Invalid channel count %1").arg(channels)); 65 70 } 66 71 67 72 // dsprate is in 100 * samples/second -
libs/libmythtv/avformatdecoder.h
261 261 bool allow_ac3_passthru; 262 262 bool allow_dts_passthru; 263 263 bool disable_passthru; 264 uint max_channels; 265 264 266 VideoFrame *dummy_frame; 265 267 266 268 AudioInfo audioIn; -
libs/libmythtv/avformatdecoder.cpp
51 51 52 52 #define MAX_AC3_FRAME_SIZE 6144 53 53 54 /** Set to zero to allow any number of AC3 channels. */55 #define MAX_OUTPUT_CHANNELS 256 57 54 static int cc608_parity(uint8_t byte); 58 55 static int cc608_good_parity(const int *parity_table, uint16_t data); 59 56 static void cc608_build_parity_table(int *parity_table); … … 400 397 // Audio 401 398 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 402 399 allow_ac3_passthru(false), allow_dts_passthru(false), 403 disable_passthru(false), dummy_frame(NULL), 400 disable_passthru(false), max_channels(2), 401 dummy_frame(NULL), 404 402 // DVD 405 403 lastdvdtitle(-1), lastcellstart(0), 406 404 dvdmenupktseen(false), indvdstill(false), … … 417 415 418 416 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 419 417 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 418 max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2); 420 419 421 420 audioIn.sample_size = -32; // force SetupAudioStream to run once 422 421 itv = GetNVP()->GetInteractiveTV(); … … 1587 1586 <<") already open, leaving it alone."); 1588 1587 } 1589 1588 //assert(enc->codec_id); 1589 VERBOSE(VB_GENERAL, LOC + QString("codec %1 has %2 channels") 1590 .arg(codec_id_string(enc->codec_id)) 1591 .arg(enc->channels)); 1590 1592 1593 #if 0 1594 // HACK MULTICHANNEL DTS passthru disabled for multichannel, 1595 // dont know how to handle this 1591 1596 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1592 1597 if (enc->codec_id == CODEC_ID_DTS) 1593 1598 { … … 1596 1601 // enc->bit_rate = what??; 1597 1602 } 1598 1603 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1604 #endif 1599 1605 1600 1606 bitrate += enc->bit_rate; 1601 1607 break; … … 3296 3302 3297 3303 // detect channels on streams that need 3298 3304 // to be decoded before we can know this 3305 int prev_channels = curstream->codec->channels; 3306 bool already_decoded = false; 3299 3307 if (!curstream->codec->channels) 3300 3308 { 3301 3309 QMutexLocker locker(&avcodeclock); 3302 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 3310 VERBOSE(VB_IMPORTANT, LOC + 3311 QString("Setting channels to %1") 3312 .arg(audioOut.channels)); 3313 3314 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3315 (curstream->codec->codec_id == CODEC_ID_AC3)); 3316 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3317 (curstream->codec->codec_id == CODEC_ID_DTS)); 3318 bool using_passthru = do_ac3_passthru || do_dts_passthru; 3319 if (using_passthru) 3320 { 3321 // for passthru let it select the max number of channels 3322 curstream->codec->channels = 0; 3323 curstream->codec->request_channels = 0; 3324 } 3325 else 3326 { 3327 curstream->codec->channels = audioOut.channels; 3328 curstream->codec->request_channels = audioOut.channels; 3329 } 3303 3330 ret = avcodec_decode_audio( 3304 3331 curstream->codec, audioSamples, 3305 3332 &data_size, ptr, len); 3333 already_decoded = true; 3306 3334 3307 3335 reselectAudioTrack |= curstream->codec->channels; 3308 3336 } … … 3360 3388 AVCodecContext *ctx = curstream->codec; 3361 3389 3362 3390 if ((ctx->channels == 0) || 3363 (ctx->channels > MAX_OUTPUT_CHANNELS))3364 ctx->channels = MAX_OUTPUT_CHANNELS;3391 (ctx->channels > audioOut.channels)) 3392 ctx->channels = audioOut.channels; 3365 3393 3366 ret = avcodec_decode_audio( 3367 ctx, audioSamples, &data_size, ptr, len); 3394 if (!already_decoded) 3395 { 3396 curstream->codec->request_channels = audioOut.channels; 3397 ret = avcodec_decode_audio( 3398 ctx, audioSamples, &data_size, ptr, len); 3399 } 3368 3400 3369 3401 // When decoding some audio streams the number of 3370 3402 // channels, etc isn't known until we try decoding it. … … 3799 3831 3800 3832 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3801 3833 { 3834 // can only disable never reenable as once 3835 // timestretch is on its on for the session 3836 if (disable_passthru) 3837 return; 3838 3802 3839 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3803 3840 { 3804 3841 disable_passthru = disable; … … 3831 3868 AVCodecContext *codec_ctx = NULL; 3832 3869 AudioInfo old_in = audioIn; 3833 3870 AudioInfo old_out = audioOut; 3871 bool using_passthru = false; 3834 3872 3835 3873 if ((currentTrack[kTrackTypeAudio] >= 0) && 3836 3874 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3842 3880 assert(curstream->codec); 3843 3881 codec_ctx = curstream->codec; 3844 3882 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3845 !disable_passthru &&3846 3883 (codec_ctx->codec_id == CODEC_ID_AC3)); 3847 3884 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3848 !disable_passthru &&3849 3885 (codec_ctx->codec_id == CODEC_ID_DTS)); 3886 using_passthru = do_ac3_passthru || do_dts_passthru; 3850 3887 info = AudioInfo(codec_ctx->codec_id, 3851 3888 codec_ctx->sample_rate, codec_ctx->channels, 3852 do_ac3_passthru || do_dts_passthru);3889 using_passthru && !disable_passthru); 3853 3890 } 3854 3891 3855 3892 if (info == audioIn) 3856 3893 return false; // no change 3857 3894 3895 QString ptmsg = (using_passthru) ? " using passthru" : ""; 3858 3896 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3859 3897 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3860 3898 3861 3899 audioOut = audioIn = info; 3862 if ( audioIn.do_passthru)3900 if (using_passthru) 3863 3901 { 3864 3902 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3865 audioOut.channels = 2; 3866 audioOut.sample_rate = 48000; 3867 audioOut.sample_size = 4; 3903 AudioInfo digInfo = audioOut; 3904 if (!disable_passthru) 3905 { 3906 digInfo.channels = 2; 3907 digInfo.sample_rate = 48000; 3908 digInfo.sample_size = 4; 3909 } 3910 if (audioOut.channels > (int) max_channels) 3911 { 3912 audioOut.channels = (int) max_channels; 3913 audioOut.sample_size = audioOut.channels * 2; 3914 codec_ctx->channels = audioOut.channels; 3915 } 3916 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3917 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3918 .arg(digInfo.toString()) 3919 .arg(old_in.toString()).arg(old_out.toString()) 3920 .arg(audioIn.toString()).arg(audioOut.toString())); 3921 3922 if (digInfo.sample_rate > 0) 3923 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3924 3925 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3926 digInfo.sample_rate, audioIn.do_passthru); 3927 // allow the audio stuff to reencode 3928 GetNVP()->SetAudioCodec(codec_ctx); 3929 GetNVP()->ReinitAudio(); 3930 return true; 3868 3931 } 3869 3932 else 3870 3933 { 3871 if (audioOut.channels > MAX_OUTPUT_CHANNELS)3934 if (audioOut.channels > (int) max_channels) 3872 3935 { 3873 audioOut.channels = MAX_OUTPUT_CHANNELS;3936 audioOut.channels = (int) max_channels; 3874 3937 audioOut.sample_size = audioOut.channels * 2; 3875 codec_ctx->channels = MAX_OUTPUT_CHANNELS;3938 codec_ctx->channels = audioOut.channels; 3876 3939 } 3877 3940 } 3878 3941 … … 3887 3950 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3888 3951 audioOut.sample_rate, 3889 3952 audioIn.do_passthru); 3890 GetNVP()->ReinitAudio();3891 3953 3954 // allow the audio stuff to reencode 3955 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3956 QString errMsg = GetNVP()->ReinitAudio(); 3957 bool audiook = errMsg.isEmpty(); 3958 3892 3959 return true; 3893 3960 } 3894 3961 -
libs/libmythtv/NuppelVideoPlayer.h
127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 void SetAudioCodec(void *ac); 130 131 131 132 // Sets 132 133 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 684 685 int audio_bits; 685 686 int audio_samplerate; 686 687 float audio_stretchfactor; 688 void *audio_codec; 687 689 bool audio_passthru; 688 690 689 691 // Picture-in-Picture -
libs/libmythtv/NuppelVideoPlayer.cpp
207 207 audio_passthru_device(QString::null), 208 208 audio_channels(2), audio_bits(-1), 209 209 audio_samplerate(44100), audio_stretchfactor(1.0f), 210 audio_codec(NULL), 210 211 // Picture-in-Picture 211 212 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 212 213 // Preview window support … … 772 773 if (audioOutput) 773 774 { 774 775 audioOutput->Reconfigure(audio_bits, audio_channels, 775 audio_samplerate, audio_passthru); 776 audio_samplerate, audio_passthru, 777 audio_codec); 776 778 errMsg = audioOutput->GetError(); 777 779 if (!errMsg.isEmpty()) 778 780 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3657 3664 audio_passthru = passthru; 3658 3665 } 3659 3666 3667 void NuppelVideoPlayer::SetAudioCodec(void *ac) 3668 { 3669 audio_codec = ac; 3670 } 3671 3660 3672 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3661 3673 { 3662 3674 if (audioOutput) -
libs/libavcodec/liba52.c
134 134 } 135 135 } 136 136 137 static inline int16_t convert(int32_t i) 138 { 139 return av_clip_int16(i - 0x43c00000); 140 } 141 142 void float2s16_2 (float * _f, int16_t * s16) 143 { 144 int i; 145 int32_t * f = (int32_t *) _f; 146 147 for (i = 0; i < 256; i++) { 148 s16[2*i] = convert (f[i]); 149 s16[2*i+1] = convert (f[i+256]); 150 } 151 } 152 153 void float2s16_4 (float * _f, int16_t * s16) 154 { 155 int i; 156 int32_t * f = (int32_t *) _f; 157 158 for (i = 0; i < 256; i++) { 159 s16[4*i] = convert (f[i]); 160 s16[4*i+1] = convert (f[i+256]); 161 s16[4*i+2] = convert (f[i+512]); 162 s16[4*i+3] = convert (f[i+768]); 163 } 164 } 165 166 void float2s16_5 (float * _f, int16_t * s16) 167 { 168 int i; 169 int32_t * f = (int32_t *) _f; 170 171 for (i = 0; i < 256; i++) { 172 s16[5*i] = convert (f[i]); 173 s16[5*i+1] = convert (f[i+256]); 174 s16[5*i+2] = convert (f[i+512]); 175 s16[5*i+3] = convert (f[i+768]); 176 s16[5*i+4] = convert (f[i+1024]); 177 } 178 } 179 180 #define LIKEAC3DEC 1 181 int channels_multi (int flags) 182 { 183 if (flags & A52_LFE) 184 return 6; 185 else if (flags & 1) /* center channel */ 186 return 5; 187 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 188 return 4; 189 else 190 return 2; 191 } 192 193 void float2s16_multi (float * _f, int16_t * s16, int flags) 194 { 195 int i; 196 int32_t * f = (int32_t *) _f; 197 198 switch (flags) { 199 case A52_MONO: 200 for (i = 0; i < 256; i++) { 201 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 202 s16[5*i+4] = convert (f[i]); 203 } 204 break; 205 case A52_CHANNEL: 206 case A52_STEREO: 207 case A52_DOLBY: 208 float2s16_2 (_f, s16); 209 break; 210 case A52_3F: 211 for (i = 0; i < 256; i++) { 212 s16[5*i] = convert (f[i]); 213 s16[5*i+1] = convert (f[i+512]); 214 s16[5*i+2] = s16[5*i+3] = 0; 215 s16[5*i+4] = convert (f[i+256]); 216 } 217 break; 218 case A52_2F2R: 219 float2s16_4 (_f, s16); 220 break; 221 case A52_3F2R: 222 float2s16_5 (_f, s16); 223 break; 224 case A52_MONO | A52_LFE: 225 for (i = 0; i < 256; i++) { 226 #if LIKEAC3DEC 227 s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 228 s16[6*i+1] = convert (f[i+256]); 229 s16[6*i+5] = convert (f[i]); 230 #else 231 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 232 s16[6*i+4] = convert (f[i+256]); 233 s16[6*i+5] = convert (f[i]); 234 #endif 235 } 236 break; 237 case A52_CHANNEL | A52_LFE: 238 case A52_STEREO | A52_LFE: 239 case A52_DOLBY | A52_LFE: 240 for (i = 0; i < 256; i++) { 241 #if LIKEAC3DEC 242 s16[6*i] = convert (f[i+256]); 243 s16[6*i+2] = convert (f[i+512]); 244 s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0; 245 s16[6*i+5] = convert (f[i]); 246 #else 247 s16[6*i] = convert (f[i+256]); 248 s16[6*i+1] = convert (f[i+512]); 249 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 250 s16[6*i+5] = convert (f[i]); 251 #endif 252 } 253 break; 254 case A52_3F | A52_LFE: 255 for (i = 0; i < 256; i++) { 256 #if LIKEAC3DEC 257 s16[6*i] = convert (f[i+256]); 258 s16[6*i+2] = convert (f[i+768]); 259 s16[6*i+3] = s16[6*i+4] = 0; 260 s16[6*i+1] = convert (f[i+512]); 261 s16[6*i+5] = convert (f[i]); 262 #else 263 s16[6*i] = convert (f[i+256]); 264 s16[6*i+1] = convert (f[i+768]); 265 s16[6*i+2] = s16[6*i+3] = 0; 266 s16[6*i+4] = convert (f[i+512]); 267 s16[6*i+5] = convert (f[i]); 268 #endif 269 } 270 break; 271 case A52_2F2R | A52_LFE: 272 for (i = 0; i < 256; i++) { 273 #if LIKEAC3DEC 274 s16[6*i] = convert (f[i+256]); 275 s16[6*i+1] = 0; 276 s16[6*i+2] = convert (f[i+512]); 277 s16[6*i+3] = convert (f[i+768]); 278 s16[6*i+4] = convert (f[i+1024]); 279 s16[6*i+5] = convert (f[i]); 280 #else 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+512]); 283 s16[6*i+2] = convert (f[i+768]); 284 s16[6*i+3] = convert (f[i+1024]); 285 s16[6*i+4] = 0; 286 s16[6*i+5] = convert (f[i]); 287 #endif 288 } 289 break; 290 case A52_3F2R | A52_LFE: 291 for (i = 0; i < 256; i++) { 292 #if LIKEAC3DEC 293 s16[6*i] = convert (f[i+256]); 294 s16[6*i+1] = convert (f[i+512]); 295 s16[6*i+2] = convert (f[i+768]); 296 s16[6*i+3] = convert (f[i+1024]); 297 s16[6*i+4] = convert (f[i+1280]); 298 s16[6*i+5] = convert (f[i]); 299 #else 300 s16[6*i] = convert (f[i+256]); 301 s16[6*i+1] = convert (f[i+768]); 302 s16[6*i+2] = convert (f[i+1024]); 303 s16[6*i+3] = convert (f[i+1280]); 304 s16[6*i+4] = convert (f[i+512]); 305 s16[6*i+5] = convert (f[i]); 306 #endif 307 } 308 break; 309 } 310 } 311 137 312 /**** end */ 138 313 139 314 #define HEADER_SIZE 7 … … 179 354 s->channels = ac3_channels[s->flags & 7]; 180 355 if (s->flags & A52_LFE) 181 356 s->channels++; 357 if (avctx->request_channels > 0) 358 { 359 avctx->channels = s->channels; 360 if (s->channels > avctx->channels) 361 avctx->channels = avctx->request_channels; 362 } 182 363 if (avctx->channels == 0) 183 364 /* No specific number of channel requested */ 184 365 avctx->channels = s->channels; … … 199 380 s->inbuf_ptr += len; 200 381 buf_size -= len; 201 382 } else { 383 int chans; 202 384 flags = s->flags; 203 385 if (avctx->channels == 1) 204 386 flags = A52_MONO; 205 else if (avctx->channels == 2) 206 flags = A52_STEREO; 387 else if (avctx->channels == 2) { 388 if (s->channels>2) 389 flags = A52_DOLBY; 390 else 391 flags = A52_STEREO; 392 } 207 393 else 208 394 flags |= A52_ADJUST_LEVEL; 209 395 level = 1; 396 chans = channels_multi(flags); 210 397 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 211 398 fail: 212 399 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 217 404 for (i = 0; i < 6; i++) { 218 405 if (s->a52_block(s->state)) 219 406 goto fail; 220 float _to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);407 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 221 408 } 222 409 s->inbuf_ptr = s->inbuf; 223 410 s->frame_size = 0; -
libs/libavcodec/ac3dec.c
1132 1132 1133 1133 /* channel config */ 1134 1134 ctx->out_channels = ctx->nchans; 1135 if (avctx->request_channels > 0) 1136 { 1137 avctx->channels = ctx->out_channels; 1138 if (avctx->channels > avctx->request_channels) 1139 avctx->channels = avctx->request_channels; 1140 } 1135 1141 if (avctx->channels == 0) { 1136 1142 avctx->channels = ctx->out_channels; 1137 1143 } else if(ctx->out_channels < avctx->channels) { -
libs/libavcodec/dca.c
1159 1159 avctx->bit_rate = s->bit_rate; 1160 1160 1161 1161 channels = s->prim_channels + !!s->lfe; 1162 avctx->channels = avctx->request_channels; 1162 //avctx->channels = avctx->request_channels; 1163 if (avctx->request_channels > 0) 1164 { 1165 avctx->channels = channels; 1166 if (avctx->channels > avctx->request_channels) 1167 avctx->channels = avctx->request_channels; 1168 } 1163 1169 if(avctx->channels == 0) { 1164 1170 avctx->channels = channels; 1165 1171 } else if(channels < avctx->channels) {