Ticket #1104: mythtv_ac3.48.patch

File mythtv_ac3.48.patch, 70.7 KB (added by Mark Spieth, 16 years ago)

fixed passthru and intrastream channel switch hiccup

  • configure

     
    752752    libfaac
    753753    libfaad
    754754    libfaadbin
     755    libfftw3
    755756    libgsm
    756757    libmp3lame
    757758    libnut
     
    28862887echo "libfaac enabled           ${libfaac-no}"
    28872888echo "libfaad enabled           ${libfaad-no}"
    28882889echo "libfaad dlopened          ${libfaadbin-no}"
     2890echo "libfftw3 support          ${liba52-no}"
    28892891echo "libgsm enabled            ${libgsm-no}"
    28902892echo "libmp3lame enabled        ${libmp3lame-no}"
    28912893echo "libnut enabled            ${libnut-no}"
  • libs/libs.pro

     
    66# Directories
    77SUBDIRS += libavutil libavcodec libavformat libmythsamplerate
    88SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav
     9SUBDIRS += libmythfreesurround
    910
    1011mingw : SUBDIRS += libmyth libmythupnp libmythui
    1112!mingw: SUBDIRS += libmythupnp libmythui libmyth
  • libs/libmyth/libmyth.pro

     
    1111
    1212# Input
    1313HEADERS += audiooutput.h audiooutputbase.h audiooutputnull.h
     14HEADERS += audiooutputdigitalencoder.h
    1415HEADERS += backendselect.h dbsettings.h dialogbox.h
    1516HEADERS += DisplayRes.h DisplayResScreen.h exitcodes.h
    1617HEADERS += generictree.h httpcomms.h langsettings.h lcddevice.h
     
    2526HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h
    2627HEADERS += mythhdd.h mythcdrom.h
    2728HEADERS += compat.h
     29HEADERS += audiooutputdigitalencoder.h
    2830
    2931SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
     32SOURCES += audiooutputdigitalencoder.cpp
    3033SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
    3134SOURCES += DisplayRes.cpp DisplayResScreen.cpp
    3235SOURCES += generictree.cpp httpcomms.cpp langsettings.cpp lcddevice.cpp
     
    4144SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp
    4245SOURCES += mythhdd.cpp mythcdrom.cpp
    4346
    44 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./
     47INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../libmythfreesurround
     48INCLUDEPATH += ../libavcodec ../libavutil
     49INCLUDEPATH += ../.. ../ ./
    4550DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
    46 DEPENDPATH += ../libmythupnp
     51DEPENDPATH += ../libmythupnp ../libmythfreesurround ../libavcodec ../libavutil
    4752
    48 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    49 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
    50 LIBS += -L../libmythui         -lmythui-$${LIBVERSION}
    51 LIBS += -L../libmythupnp       -lmythupnp-$${LIBVERSION}
    5253
     54LIBS += -L../libmythsamplerate   -lmythsamplerate-$${LIBVERSION}
     55LIBS += -L../libmythsoundtouch   -lmythsoundtouch-$${LIBVERSION}
     56LIBS += -L../libmythui           -lmythui-$${LIBVERSION}
     57LIBS += -L../libmythupnp         -lmythupnp-$${LIBVERSION}
     58LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION}
     59LIBS += -L../libavcodec          -lmythavcodec-$${LIBVERSION}
     60LIBS += -L../libavutil           -lmythavutil-$${LIBVERSION}
     61
    5362TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
    5463TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT}
     64TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT}
    5565
    5666# Install headers so that plugins can compile independently
    5767inc.path = $${PREFIX}/include/mythtv/
     
    221231use_hidesyms {
    222232    QMAKE_CXXFLAGS += -fvisibility=hidden
    223233}
     234
     235contains( CONFIG_LIBA52, yes ) {
     236    LIBS += -la52
     237}
     238
     239contains( CONFIG_LIBFFTW3, yes ) {
     240    LIBS += -lfftw3f
     241}
  • libs/libmyth/audiooutput.h

     
    3131    virtual ~AudioOutput() { };
    3232
    3333    // 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;
    3639   
    3740    virtual void SetStretchFactor(float factor);
     41    virtual float GetStretchFactor(void) { return 1.0f; }
    3842
    3943    // do AddSamples calls block?
    4044    virtual void SetBlocking(bool blocking) = 0;
     
    7680        lastError = msg;
    7781        VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError);
    7882    }
     83    void ClearError(void) { lastError = QString::null; }
    7984
    8085    void Warn(QString msg)
    8186    {
  • libs/libmyth/audiooutputdx.h

     
    3535    /// END HACK HACK HACK HACK
    3636       
    3737    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);
    4043    virtual void SetBlocking(bool blocking);
    4144
    4245    virtual bool AddSamples(char *buffer, int samples, long long timecode);
  • libs/libmyth/audiooutputdx.cpp

     
    130130    // FIXME: kedl: not sure what else could be required here?
    131131}
    132132
    133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels,
    134                                 int audio_samplerate, int audio_passthru)
     133void AudioOutputDX::Reconfigure(int audio_bits,
     134                                int audio_channels,
     135                                int audio_samplerate,
     136                                int audio_passthru,
     137                                AudioCodecMode laom)
    135138{
    136139    if (dsbuffer)
    137140        DestroyDSBuffer();
  • libs/libmyth/audiooutputbase.h

     
    1616// MythTV headers
    1717#include "audiooutput.h"
    1818#include "samplerate.h"
    19 #include "SoundTouch.h"
    2019
    21 #define AUDBUFSIZE 768000
     20namespace soundtouch {
     21class SoundTouch;
     22};
     23class FreeSurround;
     24class AudioOutputDigitalEncoder;
     25struct AVCodecContext;
     26
    2227#define AUDIO_SRC_IN_SIZE   16384
    2328#define AUDIO_SRC_OUT_SIZE (16384*6)
    2429#define AUDIO_TMP_BUF_SIZE (16384*6)
    2530
     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
    2636class AudioOutputBase : public AudioOutput
    2737{
    2838 public:
     
    3545    virtual ~AudioOutputBase();
    3646
    3747    // 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);
    4053   
    4154    // do AddSamples calls block?
    4255    virtual void SetBlocking(bool blocking);
     
    4558    virtual void SetEffDsp(int dsprate);
    4659
    4760    virtual void SetStretchFactor(float factor);
     61    virtual float GetStretchFactor(void);
    4862
    4963    virtual void Reset(void);
    5064
     
    127141    bool audio_passthru;
    128142
    129143    float audio_stretchfactor;
     144    AVCodecContext *audio_codec;
    130145    AudioOutputSource source;
    131146
    132147    bool killaudio;
     
    135150    bool set_initial_vol;
    136151    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    137152   
     153    int configured_audio_channels;
     154
    138155 private:
    139156    // resampler
    140157    bool need_resampler;
     
    145162    short tmp_buff[AUDIO_TMP_BUF_SIZE];
    146163
    147164    // timestretch
    148     soundtouch::SoundTouch * pSoundStretch;
     165    soundtouch::SoundTouch    *pSoundStretch;
     166    AudioOutputDigitalEncoder *encoder;
     167    FreeSurround              *upmixer;
    149168
     169    int source_audio_channels;
     170    int source_audio_bytes_per_sample;
     171    bool needs_upmix;
     172    int surround_mode;
     173
    150174    bool blocking; // do AddSamples calls block?
    151175
    152176    int lastaudiolen;
     
    164188
    165189    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    166190                                    'audiotime' and 'audiotime_updated' */
    167     int audiotime; // timecode of audio leaving the soundcard (same units as
    168                    //                                          timecodes) ...
     191    /// timecode of audio leaving the soundcard (same units as timecodes)
     192    long long audiotime;
    169193    struct timeval audiotime_updated; // ... which was last updated at this time
    170194
    171195    /* Audio circular buffer */
    172196    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    173197    int raud, waud;     /* read and write positions */
    174     int audbuf_timecode;    /* timecode of audio most recently placed into
    175                    buffer */
     198    /// timecode of audio most recently placed into buffer
     199    long long audbuf_timecode;
    176200
    177201    int numlowbuffer;
    178202
  • libs/libmyth/audiooutputbase.cpp

     
    1515
    1616// MythTV headers
    1717#include "audiooutputbase.h"
     18#include "audiooutputdigitalencoder.h"
     19#include "SoundTouch.h"
     20#include "freesurround.h"
    1821#include "compat.h"
    1922
    2023#define LOC QString("AO: ")
     
    3639    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
    3740    audio_passthru(false),      audio_stretchfactor(1.0f),
    3841
     42    audio_codec(NULL),
    3943    source(lsource),            killaudio(false),
    4044
    4145    pauseaudio(false),          audio_actually_paused(false),
     
    4751
    4852    src_ctx(NULL),
    4953
    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),
    5161
     62    blocking(false),
     63
    5264    lastaudiolen(0),            samples_buffered(0),
    5365
    5466    audio_thread_exists(false),
     
    7183    memset(tmp_buff,           0, sizeof(short) * AUDIO_TMP_BUF_SIZE);
    7284    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    7385    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
     86    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    7487
    7588    // You need to call Reconfigure from your concrete class.
    7689    // Reconfigure(laudio_bits,       laudio_channels,
     
    111124            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    112125                                        .arg(audio_stretchfactor));
    113126            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));
    116135
     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
    117162            pSoundStretch->setTempo(audio_stretchfactor);
    118163            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
    119164
     
    134179    pthread_mutex_unlock(&audio_buflock);
    135180}
    136181
     182float AudioOutputBase::GetStretchFactor()
     183{
     184    return audio_stretchfactor;
     185}
     186
    137187void 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)
    139190{
    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");
    143234        return;
     235    }
    144236
     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
    145245    KillAudio();
    146246   
    147247    pthread_mutex_lock(&audio_buflock);
     
    151251    waud = raud = 0;
    152252    audio_actually_paused = false;
    153253   
     254    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154255    audio_channels = laudio_channels;
     256    source_audio_channels = lsource_audio_channels;
    155257    audio_bits = laudio_bits;
    156258    audio_samplerate = laudio_samplerate;
     259    audio_codec = (AVCodecContext*)laudio_codec;
    157260    audio_passthru = laudio_passthru;
     261    needs_upmix = lneeds_upmix;
     262
    158263    if (audio_bits != 8 && audio_bits != 16)
    159264    {
    160265        pthread_mutex_unlock(&avsync_lock);
     
    162267        Error("AudioOutput only supports 8 or 16bit audio.");
    163268        return;
    164269    }
     270
    165271    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     272    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    166273   
    167274    need_resampler = false;
    168275    killaudio = false;
     
    172279   
    173280    numlowbuffer = 0;
    174281
     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 
    175286    // Actually do the device specific open call
    176287    if (!OpenDevice())
    177288    {
    178289        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179290        pthread_mutex_unlock(&avsync_lock);
    180291        pthread_mutex_unlock(&audio_buflock);
     292        if (GetError().isEmpty())
     293            Error("Aborting reconfigure");
     294        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181295        return;
    182296    }
    183297
     
    200314    current_seconds = -1;
    201315    source_bitrate = -1;
    202316
     317    // NOTE: this won't do anything as above samplerate vars are set equal
    203318    // Check if we need the resampler
    204319    if (audio_samplerate != laudio_samplerate)
    205320    {
     
    222337        need_resampler = true;
    223338    }
    224339
     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
    225358    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226359            .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"));
    227363
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     364    if (redo_stretch)
    230365    {
    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);
    233371    }
     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));
    234385
     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
    235413    // Setup visualisations, zero the visualisations buffers
    236414    prepareVisuals();
    237415
     
    290468        pSoundStretch = NULL;
    291469    }
    292470
     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
    293484    CloseDevice();
    294485
    295486    killAudioLock.unlock();
     
    303494
    304495void AudioOutputBase::Pause(bool paused)
    305496{
     497    VERBOSE(VB_AUDIO, LOC + QString("Pause %0").arg(paused));
    306498    pauseaudio = paused;
    307499    audio_actually_paused = false;
    308500}
     
    385577       The reason is that computing 'audiotime' requires acquiring the audio
    386578       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387579       from the audio thread, and then call this from the video thread. */
    388     int ret;
     580    long long ret;
    389581    struct timeval now;
    390582
    391583    if (audiotime == 0)
     
    397589
    398590    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399591    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     592    ret = (long long)(ret * audio_stretchfactor);
    401593
     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
    402605    ret += audiotime;
    403606
    404607    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     608    return (int)ret;
    406609}
    407610
    408611void AudioOutputBase::SetAudiotime(void)
     
    439642    // include algorithmic latencies
    440643    if (pSoundStretch)
    441644    {
     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);
    442649        // add the effect of unprocessed samples in time stretch algo
    443650        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444651                              audio_bytes_per_sample) / audio_stretchfactor);
    445652    }
    446                
     653
     654    if (upmixer && needs_upmix)
     655    {
     656        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     657    }
     658
    447659    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448660                                   (audio_bytes_per_sample * effdspstretched));
    449661 
    450662    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
    451677
    452678    pthread_mutex_unlock(&avsync_lock);
    453679    pthread_mutex_unlock(&audio_buflock);
     
    458684{
    459685    // NOTE: This function is not threadsafe
    460686    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;
    462689    int len = samples * abps;
    463690
    464691    // Check we have enough space to write the data
    465692    if (need_resampler && src_ctx)
    466693        len = (int)ceilf(float(len) * src_data.src_ratio);
    467694
     695    // include samples in upmix buffer that may be flushed
     696    if (needs_upmix && upmixer)
     697        len += upmixer->numUnprocessedSamples() * abps;
     698
    468699    if (pSoundStretch)
    469700        len += (pSoundStretch->numUnprocessedSamples() +
    470701                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     
    520751    // NOTE: This function is not threadsafe
    521752
    522753    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;
    524756    int len = samples * abps;
    525757
    526758    // Check we have enough space to write the data
    527759    if (need_resampler && src_ctx)
    528760        len = (int)ceilf(float(len) * src_data.src_ratio);
    529761
     762    // include samples in upmix buffer that may be flushed
     763    if (needs_upmix && upmixer)
     764        len += upmixer->numUnprocessedSamples() * abps;
     765 
    530766    if (pSoundStretch)
    531767    {
    532768        len += (pSoundStretch->numUnprocessedSamples() +
     
    575811
    576812int AudioOutputBase::WaitForFreeSpace(int samples)
    577813{
    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;
    579817    int afree = audiofree(false);
    580818
    581819    while (len > afree)
    582820    {
    583821        if (blocking)
    584822        {
    585             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     823            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    586824                    QString("(need %1, available %2)").arg(len).arg(afree));
    587825
    588826            // wait for more space
     
    591829        }
    592830        else
    593831        {
    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;
    598837            if (src_ctx)
    599838            {
    600839                int error = src_reset(src_ctx);
     
    619858   
    620859    int afree = audiofree(false);
    621860
    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));
    626871   
    627     len = WaitForFreeSpace(samples);
    628 
    629     if (interleaved)
     872    if (upmixer && needs_upmix)
    630873    {
    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; )
    634878        {
    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            }
    637923        }
    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
    644931    {
    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)
    647935        {
    648             for (int chan = 0; chan < audio_channels; chan++)
     936            char *mybuf = (char*)buffer;
     937            int bdiff = AUDBUFSIZE - org_waud;
     938            if (bdiff < len)
    649939            {
    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];
    653961
    654                 if (org_waud >= AUDBUFSIZE)
    655                     org_waud -= AUDBUFSIZE;
     962                    if (org_waud >= AUDBUFSIZE)
     963                        org_waud -= AUDBUFSIZE;
     964                }
    656965            }
    657966        }
    658967    }
    659968
    660     if (pSoundStretch)
     969    if (samples > 0)
    661970    {
    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)
    668972        {
    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         else
    675         {
    676             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    677                                       org_waud), len / audio_bytes_per_sample);
    678         }
    679973
    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)
    688980            {
    689                 samplesToGet = nSamplesToEnd;   
     981                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     982                                          (audiobuffer +
     983                                           org_waud), nSamplesToEnd);
     984                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     985                                          (len - bdiff) / abps);
    690986            }
     987            else
     988            {
     989                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     990                                          (audiobuffer + org_waud),
     991                                          len / abps);
     992            }
    691993
    692             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    693                                       (audiobuffer + org_waud), samplesToGet);
    694             if (nSamples == nSamplesToEnd)
     994            if (encoder)
    695995            {
    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                }
    6981040            }
    6991041            else
    7001042            {
    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);
    7031072            }
     1073        }
    7041074
    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);
    7091077
    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);
    7121091
    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        }
    7191097    }
    720    
    721     /* we want the time at the end -- but the file format stores
    722        time at the start of the chunk. */
    723     // even with timestretch, timecode is still calculated from original
    724     // sample count
    725     audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7261098
    727     if (interleaved)
    728         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    729 
    7301099    pthread_mutex_unlock(&audio_buflock);
    7311100}
    7321101
     
    7391108
    7401109    if (source_bitrate == -1)
    7411110    {
    742         source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1111        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
    7431112    }
    7441113
    7451114    if (ct / 1000 != current_seconds)
     
    7471116        current_seconds = ct / 1000;
    7481117        OutputEvent e(current_seconds, ct,
    7491118                      source_bitrate, audio_samplerate, audio_bits,
    750                       audio_channels);
     1119                      source_audio_channels);
    7511120        dispatch(e);
    7521121    }
    7531122}
     
    7851154
    7861155            space_on_soundcard = getSpaceOnSoundcard();
    7871156
    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")
    7901161                        .arg(space_on_soundcard));
     1162
    7911163                last_space_on_soundcard = space_on_soundcard;
    7921164            }
    7931165
     
    7991171                    WriteAudio(zeros, fragment_size);
    8001172                } else {
    8011173                    // this should never happen now -dag
    802                     VERBOSE(VB_AUDIO, LOC +
     1174                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8031175                            QString("waiting for space on soundcard "
    8041176                                    "to write zeros: have %1 need %2")
    8051177                            .arg(space_on_soundcard).arg(fragment_size));
     
    8351207        if (fragment_size > audiolen(true))
    8361208        {
    8371209            if (audiolen(true) > 0)  // only log if we're sending some audio
    838                 VERBOSE(VB_AUDIO, LOC +
     1210                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8391211                        QString("audio waiting for buffer to fill: "
    8401212                                "have %1 want %2")
    8411213                        .arg(audiolen(true)).arg(fragment_size));
    8421214
    843             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1215            //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1216            //LOC + "Broadcasting free space avail");
    8441217            pthread_mutex_lock(&audio_buflock);
    8451218            pthread_cond_broadcast(&audio_bufsig);
    8461219            pthread_mutex_unlock(&audio_buflock);
     
    8541227        if (fragment_size > space_on_soundcard)
    8551228        {
    8561229            if (space_on_soundcard != last_space_on_soundcard) {
    857                 VERBOSE(VB_AUDIO, LOC +
     1230                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8581231                        QString("audio waiting for space on soundcard: "
    8591232                                "have %1 need %2")
    8601233                        .arg(space_on_soundcard).arg(fragment_size));
     
    9161289
    9171290        /* update raud */
    9181291        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");
    9201293        pthread_cond_broadcast(&audio_bufsig);
    9211294
    9221295        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

     
    8989    }
    9090    else
    9191    {
    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;
    9495        period_time = buffer_time / 4;  // 4 interrupts per buffer
    9596    }
    9697
     
    162163   
    163164    tmpbuf = aubuf;
    164165
    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)")
    166168            .arg(size).arg(frames));
    167169   
    168170    while (frames > 0)
  • libs/libmythfreesurround/el_processor.cpp

     
    2020#include <complex>
    2121#include <cmath>
    2222#include <vector>
     23#ifdef USE_FFTW3
    2324#include "fftw3.h"
     25#else
     26extern "C" {
     27#include "dsputil.h"
     28};
     29typedef FFTSample FFTComplexArray[2];
     30#endif
    2431
    2532#define FILTERED_LFE
    2633
     34#ifdef USE_FFTW3
    2735#pragma comment (lib,"libfftw3f-3.lib")
     36#endif
    2837
    2938typedef std::complex<float> cfloat;
    3039
     
    4554    // create an instance of the decoder
    4655    //  blocksize is fixed over the lifetime of this object for performance reasons
    4756    decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
     57#ifdef USE_FFTW3
    4858        // create FFTW buffers
    4959        lt = (float*)fftwf_malloc(sizeof(float)*N);
    5060        rt = (float*)fftwf_malloc(sizeof(float)*N);
     
    5565        loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE);
    5666        loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE);
    5767        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
    5883        // resize our own buffers
    5984        frontR.resize(N);
    6085        frontL.resize(N);
     
    97122
    98123    // destructor
    99124    ~decoder_impl() {
     125#ifdef USE_FFTW3
    100126        // clean up the FFTW stuff
    101127        fftwf_destroy_plan(store);
    102128        fftwf_destroy_plan(loadR);
     
    107133        fftwf_free(dst);
    108134        fftwf_free(rt);
    109135        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
    110148    }
    111149
    112150    float ** getInputBuffers()
     
    237275            }
    238276        }
    239277
     278#ifdef USE_FFTW3
    240279        // ... and tranform it into the frequency domain
    241280        fftwf_execute(loadL);
    242281        fftwf_execute(loadR);
     282#else
     283        ff_fft_permuteRC(fftContextForward, &lt[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
    243288
    244289        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
    245290        //    but dont do DC or N/2 component
     
    447492    // filter the complex source signal and add it to target
    448493    void apply_filter(cfloat *signal, float *flt, float *target) {
    449494        // filter the signal
    450         for (unsigned f=0;f<=halfN;f++) {       
     495        unsigned f;
     496        for (f=0;f<=halfN;f++) {
    451497            src[f][0] = signal[f].real() * flt[f];
    452498            src[f][1] = signal[f].imag() * flt[f];
    453499        }
     500#ifdef USE_FFTW3
    454501        // transform into time domain
    455502        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
    456512
    457513        float* pT1   = &target[current_buf*halfN];
    458514        float* pWnd1 = &wnd[0];
     
    470526        }
    471527    }
    472528
     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
    473576    unsigned int N;                    // the block size
    474577    unsigned int halfN;                // half block size precalculated
     578#ifdef USE_FFTW3
    475579    // FFTW data structures
    476580    float *lt,*rt,*dst;                // left total, right total (source arrays), destination array
    477581    fftwf_complex *dftL,*dftR,*src;    // intermediate arrays (FFTs of lt & rt, processing source)
    478582    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
    479588    // buffers
    480589    std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain
    481590#ifdef FILTERED_LFE
  • libs/libmythfreesurround/libmythfreesurround.pro

     
    1919SOURCES += el_processor.cpp
    2020SOURCES += freesurround.cpp
    2121
    22 #required until its rewritten to use avcodec fft lib
    23 #LIBS += -lfftw3
    24 LIBS += -lfftw3f
    25 
     22contains( 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

     
    5656    }
    5757#endif
    5858#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");
    6065#endif
    6166#ifdef USING_ARTS
    6267    gc->addSelection("ARTS:", "ARTS:");
     
    7883    return gc;
    7984}
    8085
     86static 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
     99static 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
    81113static HostComboBox *PassThroughOutputDevice()
    82114{
    83115    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    32023234         vgrp0->addChild(AC3PassThrough());
    32033235         vgrp0->addChild(DTSPassThrough());
    32043236
     3237         HorizontalConfigurationGroup *agrp =
     3238             new HorizontalConfigurationGroup(false, false, true, true);
     3239         agrp->addChild(MaxAudioChannels());
     3240         agrp->addChild(AudioUpmixType());
     3241         addChild(agrp);
     3242
    32053243         VerticalConfigurationGroup *vgrp1 =
    32063244             new VerticalConfigurationGroup(false, false, true, true);
    32073245         vgrp1->addChild(AggressiveBuffer());
  • programs/mythtranscode/transcode.cpp

     
    5555
    5656    // reconfigure sound out for new params
    5757    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)
    5960    {
     61        ClearError();
    6062        (void)audio_samplerate;
    6163        (void)audio_passthru;
     64        (void)audio_codec;
    6265        bits = audio_bits;
    6366        channels = audio_channels;
    6467        bytes_per_sample = bits * channels / 8;
     68        if ((uint)audio_channels > 2)
     69            Error(QString("Invalid channel count %1").arg(channels));
    6570    }
    6671
    6772    // dsprate is in 100 * samples/second
  • libs/libmythtv/avformatdecoder.h

     
    261261    bool              allow_ac3_passthru;
    262262    bool              allow_dts_passthru;
    263263    bool              disable_passthru;
     264    uint              max_channels;
     265
    264266    VideoFrame       *dummy_frame;
    265267
    266268    AudioInfo         audioIn;
  • libs/libmythtv/avformatdecoder.cpp

     
    5151
    5252#define MAX_AC3_FRAME_SIZE 6144
    5353
    54 /** Set to zero to allow any number of AC3 channels. */
    55 #define MAX_OUTPUT_CHANNELS 2
    56 
    5754static int cc608_parity(uint8_t byte);
    5855static int cc608_good_parity(const int *parity_table, uint16_t data);
    5956static void cc608_build_parity_table(int *parity_table);
     
    400397      // Audio
    401398      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    402399      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),
    404402      // DVD
    405403      lastdvdtitle(-1), lastcellstart(0),
    406404      dvdmenupktseen(false), indvdstill(false),
     
    417415
    418416    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    419417    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     418    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
    420419
    421420    audioIn.sample_size = -32; // force SetupAudioStream to run once
    422421    itv = GetNVP()->GetInteractiveTV();
     
    15871586                            <<") already open, leaving it alone.");
    15881587                }
    15891588                //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));
    15901592
     1593#if 0
     1594                // HACK MULTICHANNEL DTS passthru disabled for multichannel,
     1595                // dont know how to handle this
    15911596                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15921597                if (enc->codec_id == CODEC_ID_DTS)
    15931598                {
     
    15961601                    // enc->bit_rate = what??;
    15971602                }
    15981603                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1604#endif
    15991605
    16001606                bitrate += enc->bit_rate;
    16011607                break;
     
    32963302
    32973303                    // detect channels on streams that need
    32983304                    // to be decoded before we can know this
     3305                    int prev_channels = curstream->codec->channels;
     3306                    bool already_decoded = false;
    32993307                    if (!curstream->codec->channels)
    33003308                    {
    33013309                        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                        }
    33033330                        ret = avcodec_decode_audio(
    33043331                            curstream->codec, audioSamples,
    33053332                            &data_size, ptr, len);
     3333                        already_decoded = true;
    33063334
    33073335                        reselectAudioTrack |= curstream->codec->channels;
    33083336                    }
     
    33603388                        AVCodecContext *ctx = curstream->codec;
    33613389
    33623390                        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;
    33653393
    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                        }
    33683400
    33693401                        // When decoding some audio streams the number of
    33703402                        // channels, etc isn't known until we try decoding it.
     
    37993831
    38003832void AvFormatDecoder::SetDisablePassThrough(bool disable)
    38013833{
     3834    // can only disable never reenable as once
     3835    // timestretch is on its on for the session
     3836    if (disable_passthru)
     3837        return;
     3838
    38023839    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    38033840    {
    38043841        disable_passthru = disable;
     
    38313868    AVCodecContext *codec_ctx = NULL;
    38323869    AudioInfo old_in  = audioIn;
    38333870    AudioInfo old_out = audioOut;
     3871    bool using_passthru = false;
    38343872
    38353873    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    38363874        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    38423880        assert(curstream->codec);
    38433881        codec_ctx = curstream->codec;       
    38443882        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3845                                 !disable_passthru &&
    38463883                                (codec_ctx->codec_id == CODEC_ID_AC3));
    38473884        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3848                                 !disable_passthru &&
    38493885                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3886        using_passthru = do_ac3_passthru || do_dts_passthru;
    38503887        info = AudioInfo(codec_ctx->codec_id,
    38513888                         codec_ctx->sample_rate, codec_ctx->channels,
    3852                          do_ac3_passthru || do_dts_passthru);
     3889                         using_passthru && !disable_passthru);
    38533890    }
    38543891
    38553892    if (info == audioIn)
    38563893        return false; // no change
    38573894
     3895    QString ptmsg = (using_passthru) ? " using passthru" : "";
    38583896    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    38593897            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    38603898
    38613899    audioOut = audioIn = info;
    3862     if (audioIn.do_passthru)
     3900    if (using_passthru)
    38633901    {
    38643902        // 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;
    38683931    }
    38693932    else
    38703933    {
    3871         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3934        if (audioOut.channels > (int) max_channels)
    38723935        {
    3873             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3936            audioOut.channels = (int) max_channels;
    38743937            audioOut.sample_size = audioOut.channels * 2;
    3875             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3938            codec_ctx->channels = audioOut.channels;
    38763939        }
    38773940    }
    38783941
     
    38873950    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    38883951                             audioOut.sample_rate,
    38893952                             audioIn.do_passthru);
    3890     GetNVP()->ReinitAudio();
    38913953
     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
    38923959    return true;
    38933960}
    38943961
  • libs/libmythtv/NuppelVideoPlayer.h

     
    127127    void SetAudioInfo(const QString &main, const QString &passthru, uint rate);
    128128    void SetAudioParams(int bits, int channels, int samplerate, bool passthru);
    129129    void SetEffDsp(int dsprate);
     130    void SetAudioCodec(void *ac);
    130131
    131132    // Sets
    132133    void SetParentWidget(QWidget *widget)     { parentWidget = widget; }
     
    684685    int      audio_bits;
    685686    int      audio_samplerate;
    686687    float    audio_stretchfactor;
     688    void    *audio_codec;
    687689    bool     audio_passthru;
    688690
    689691    // Picture-in-Picture
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    207207      audio_passthru_device(QString::null),
    208208      audio_channels(2),            audio_bits(-1),
    209209      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     210      audio_codec(NULL),
    210211      // Picture-in-Picture
    211212      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    212213      // Preview window support
     
    772773    if (audioOutput)
    773774    {
    774775        audioOutput->Reconfigure(audio_bits, audio_channels,
    775                                  audio_samplerate, audio_passthru);
     776                                 audio_samplerate, audio_passthru,
     777                                 audio_codec);
    776778        errMsg = audioOutput->GetError();
    777779        if (!errMsg.isEmpty())
    778780            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    36573664    audio_passthru = passthru;
    36583665}
    36593666
     3667void NuppelVideoPlayer::SetAudioCodec(void *ac)
     3668{
     3669    audio_codec = ac;
     3670}
     3671
    36603672void NuppelVideoPlayer::SetEffDsp(int dsprate)
    36613673{
    36623674    if (audioOutput)
  • libs/libavcodec/liba52.c

     
    134134    }
    135135}
    136136
     137static inline int16_t convert(int32_t i)
     138{
     139    return av_clip_int16(i - 0x43c00000);
     140}
     141
     142void 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
     153void 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
     166void 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
     181int 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
     193void 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
    137312/**** end */
    138313
    139314#define HEADER_SIZE 7
     
    179354                    s->channels = ac3_channels[s->flags & 7];
    180355                    if (s->flags & A52_LFE)
    181356                        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                    }
    182363                    if (avctx->channels == 0)
    183364                        /* No specific number of channel requested */
    184365                        avctx->channels = s->channels;
     
    199380            s->inbuf_ptr += len;
    200381            buf_size -= len;
    201382        } else {
     383            int chans;
    202384            flags = s->flags;
    203385            if (avctx->channels == 1)
    204386                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            }
    207393            else
    208394                flags |= A52_ADJUST_LEVEL;
    209395            level = 1;
     396            chans = channels_multi(flags);
    210397            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    211398            fail:
    212399                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    217404            for (i = 0; i < 6; i++) {
    218405                if (s->a52_block(s->state))
    219406                    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);
    221408            }
    222409            s->inbuf_ptr = s->inbuf;
    223410            s->frame_size = 0;
  • libs/libavcodec/ac3dec.c

     
    11321132
    11331133    /* channel config */
    11341134    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    }
    11351141    if (avctx->channels == 0) {
    11361142        avctx->channels = ctx->out_channels;
    11371143    } else if(ctx->out_channels < avctx->channels) {
  • libs/libavcodec/dca.c

     
    11591159    avctx->bit_rate = s->bit_rate;
    11601160
    11611161    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    }
    11631169    if(avctx->channels == 0) {
    11641170        avctx->channels = channels;
    11651171    } else if(channels < avctx->channels) {