Ticket #1104: mythtv_ac3.42.patch

File mythtv_ac3.42.patch, 124.1 KB (added by Mark Spieth, 12 years ago)
  • libs/libmyth/audiooutputdigitalencoder.cpp

     
     1// Std C headers
     2#include <cstdio>
     3
     4// libav headers
     5extern "C" {
     6#include "libavcodec/avcodec.h"
     7#ifdef ENABLE_AC3_DECODER
     8#include "libavcodec/parser.h"
     9#else
     10#include <a52dec/a52.h>
     11#endif
     12}
     13
     14// MythTV headers
     15#include "config.h"
     16#include "mythcontext.h"
     17#include "audiooutputdigitalencoder.h"
     18#include "compat.h"
     19
     20#define LOC QString("DEnc: ")
     21
     22#define MAX_AC3_FRAME_SIZE 6144
     23
     24AudioOutputDigitalEncoder::AudioOutputDigitalEncoder()
     25{
     26    av_context = NULL;
     27    outbuf = NULL;
     28    outbuf_size = 0;
     29    one_frame_bytes = 0;
     30    frame_buffer = NULL;
     31}
     32
     33AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder()
     34{
     35    Dispose();
     36}
     37
     38void AudioOutputDigitalEncoder::Dispose()
     39{
     40    if (av_context)
     41    {
     42        avcodec_close(av_context);
     43        av_free(av_context);
     44        av_context = NULL;
     45    }
     46    if (outbuf)
     47    {
     48        delete [] outbuf;
     49        outbuf = NULL;
     50        outbuf_size = 0;
     51    }
     52    if (frame_buffer)
     53    {
     54        delete [] frame_buffer;
     55        frame_buffer = NULL;
     56        one_frame_bytes = 0;
     57    }
     58}
     59
     60//CODEC_ID_AC3
     61bool AudioOutputDigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels)
     62{
     63    AVCodec * codec;
     64    int ret;
     65
     66    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4")
     67            .arg(codec_id_string(codec_id))
     68            .arg(bitrate)
     69            .arg(samplerate)
     70            .arg(channels));
     71    //codec = avcodec_find_encoder(codec_id);
     72    // always AC3 as there is no DTS encoder at the moment 2005/1/9
     73    codec = avcodec_find_encoder(CODEC_ID_AC3);
     74    if (!codec)
     75    {
     76        VERBOSE(VB_IMPORTANT,"Error: could not find codec");
     77        return false;
     78    }
     79    av_context = avcodec_alloc_context();
     80    av_context->bit_rate = bitrate;
     81    av_context->sample_rate = samplerate;
     82    av_context->channels = channels;
     83    // open it */
     84    if ((ret = avcodec_open(av_context, codec)) < 0)
     85    {
     86        VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate");
     87        Dispose();
     88        return false;
     89    }
     90
     91    size_t bytes_per_frame = av_context->channels * sizeof(short);
     92    audio_bytes_per_sample = bytes_per_frame;
     93    one_frame_bytes = bytes_per_frame * av_context->frame_size;
     94
     95    outbuf_size = 16384;    // ok for AC3 but DTS?
     96    outbuf = new char [outbuf_size];
     97    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
     98            .arg(av_context->frame_size)
     99            .arg(bytes_per_frame)
     100            .arg(one_frame_bytes)
     101           );
     102
     103    return true;
     104}
     105
     106static int DTS_SAMPLEFREQS[16] =
     107{
     108    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     109    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     110};
     111
     112static int DTS_BITRATES[30] =
     113{
     114    32000,    56000,    64000,    96000,    112000,   128000,
     115    192000,   224000,   256000,   320000,   384000,   448000,
     116    512000,   576000,   640000,   768000,   896000,   1024000,
     117    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     118    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     119};
     120
     121static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     122                             int *nblks, int *sfreq)
     123{
     124    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     125               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     126
     127    if (id != 0x7ffe8001)
     128        return -1;
     129
     130    int ftype = indata_ptr[4] >> 7;
     131
     132    int surp = (indata_ptr[4] >> 2) & 0x1f;
     133    surp = (surp + 1) % 32;
     134
     135    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     136    ++*nblks;
     137
     138    int fsize = (indata_ptr[5] & 0x03) << 12 |
     139                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     140    ++fsize;
     141
     142    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     143    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     144
     145    if (ftype != 1)
     146    {
     147        VERBOSE(VB_IMPORTANT, LOC +
     148                QString("DTS: Termination frames not handled (ftype %1)")
     149                .arg(ftype));
     150        return -1;
     151    }
     152
     153    if (*sfreq != 13)
     154    {
     155        VERBOSE(VB_IMPORTANT, LOC +
     156                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     157        return -1;
     158    }
     159
     160    if ((fsize > 8192) || (fsize < 96))
     161    {
     162        VERBOSE(VB_IMPORTANT, LOC +
     163                QString("DTS: fsize: %1 invalid").arg(fsize));
     164        return -1;
     165    }
     166
     167    if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     168        *nblks != 64 && *nblks != 128 && ftype == 1)
     169    {
     170        VERBOSE(VB_IMPORTANT, LOC +
     171                QString("DTS: nblks %1 not valid for normal frame")
     172                .arg(*nblks));
     173        return -1;
     174    }
     175
     176    return fsize;
     177}
     178
     179static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/,
     180                        int *sample_rate, int *bit_rate)
     181{
     182    int nblks;
     183    int rate;
     184    int sfreq;
     185
     186    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     187    if (fsize >= 0)
     188    {
     189        if (rate >= 0 && rate <= 29)
     190            *bit_rate = DTS_BITRATES[rate];
     191        else
     192            *bit_rate = 0;
     193        if (sfreq >= 1 && sfreq <= 15)
     194            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     195        else
     196            *sample_rate = 0;
     197    }
     198    return fsize;
     199}
     200
     201// until there is an easy way to do this with ffmpeg
     202// get the code from libavcodec/parser.c made non static
     203extern "C" int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
     204                            int *bit_rate, int *samples);
     205
     206static int encode_frame(
     207        bool dts,
     208        unsigned char *data,
     209        size_t &len)
     210{
     211    size_t enc_len;
     212    int flags, sample_rate, bit_rate;
     213
     214    // we don't do any length/crc validation of the AC3 frame here; presumably
     215    // the receiver will have enough sense to do that.  if someone has a
     216    // receiver that doesn't, here would be a good place to put in a call
     217    // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
     218    // packet is bad?  we'd need to send something that the receiver would
     219    // ignore, and if so, may as well just assume that it will ignore
     220    // anything with a bad CRC...
     221
     222    uint nr_samples = 0, block_len;
     223    if (dts)
     224    {
     225        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     226        int rate, sfreq, nblks;
     227        dts_decode_header(data+8, &rate, &nblks, &sfreq);
     228        nr_samples = nblks * 32;
     229        block_len = nr_samples * 2 * 2;
     230    }
     231    else
     232    {
     233#ifdef ENABLE_AC3_DECODER
     234        enc_len = ac3_sync(data+8, &flags, &sample_rate, &bit_rate, (int*)&block_len);
     235#else
     236        enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     237        block_len = MAX_AC3_FRAME_SIZE;
     238#endif
     239    }
     240
     241    if (enc_len == 0 || enc_len > len)
     242    {
     243        int l = len;
     244        len = 0;
     245        return l;
     246    }
     247
     248    enc_len = min((uint)enc_len, block_len - 8);
     249
     250    //uint32_t x = *(uint32_t*)(data+8);
     251    // in place swab
     252    swab(data+8, data+8, enc_len);
     253    //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     254    //        QString("DigitalEncoder::Encode swab test %1 %2")
     255    //        .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16));
     256
     257    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
     258    // they form a valid IEC958 AC3 header.
     259    data[0] = 0x72;
     260    data[1] = 0xF8;
     261    data[2] = 0x1F;
     262    data[3] = 0x4E;
     263    data[4] = 0x01;
     264    if (dts)
     265    {
     266        switch(nr_samples)
     267        {
     268            case 512:
     269                data[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     270                break;
     271
     272            case 1024:
     273                data[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     274                break;
     275
     276            case 2048:
     277                data[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     278                break;
     279
     280            default:
     281                VERBOSE(VB_IMPORTANT, LOC +
     282                        QString("DTS: %1-sample bursts not supported")
     283                        .arg(nr_samples));
     284                data[4] = 0x00;
     285                break;
     286        }
     287    }
     288    data[5] = 0x00;
     289    data[6] = (enc_len << 3) & 0xFF;
     290    data[7] = (enc_len >> 5) & 0xFF;
     291    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
     292    len = block_len;
     293
     294    return enc_len;
     295}
     296
     297// must have exactly 1 frames worth of data
     298size_t AudioOutputDigitalEncoder::Encode(short * buff)
     299{
     300    int encsize = 0;
     301    size_t outsize = 0;
     302 
     303    // put data in the correct spot for encode frame
     304    outsize = avcodec_encode_audio(
     305                av_context,
     306                ((uchar*)outbuf)+8,
     307                outbuf_size-8,
     308                buff);
     309    size_t tmpsize = outsize;
     310
     311    outsize = MAX_AC3_FRAME_SIZE;
     312    encsize = encode_frame(
     313            //av_context->codec_id==CODEC_ID_DTS,
     314            false,
     315            (unsigned char*)outbuf, outsize);
     316    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     317            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     318                .arg(tmpsize)
     319                .arg(encsize)
     320                .arg(outsize)
     321           );
     322
     323    return outsize;
     324}
  • libs/libmyth/audiooutputdigitalencoder.h

     
     1#ifndef AUDIOOUTPUTREENCODER
     2#define AUDIOOUTPUTREENCODER
     3
     4extern "C" {
     5#include "libavcodec/avcodec.h"
     6};
     7
     8class AudioOutputDigitalEncoder
     9{
     10public:
     11    AudioOutputDigitalEncoder();
     12    ~AudioOutputDigitalEncoder();
     13    void Dispose();
     14    bool Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     15    size_t Encode(short * buff);
     16
     17    // if needed
     18    char * GetFrameBuffer()
     19    {
     20        if (!frame_buffer && av_context)
     21        {
     22            frame_buffer = new char [one_frame_bytes];
     23        }
     24        return frame_buffer;
     25    }   
     26    size_t FrameSize() const { return one_frame_bytes; }
     27    char * GetOutBuff() const { return outbuf; }
     28
     29    size_t audio_bytes_per_sample;
     30private:
     31    AVCodecContext *av_context;
     32    char * outbuf;
     33    char * frame_buffer;
     34    int outbuf_size;
     35    size_t one_frame_bytes;
     36};
     37
     38
     39#endif
  • libs/libmythfreesurround/el_processor.cpp

     
     1/*
     2Copyright (C) 2007 Christian Kothe
     3
     4This program is free software; you can redistribute it and/or
     5modify it under the terms of the GNU General Public License
     6as published by the Free Software Foundation; either version 2
     7of the License, or (at your option) any later version.
     8
     9This program is distributed in the hope that it will be useful,
     10but WITHOUT ANY WARRANTY; without even the implied warranty of
     11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12GNU General Public License for more details.
     13
     14You should have received a copy of the GNU General Public License
     15along with this program; if not, write to the Free Software
     16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     17*/
     18
     19#include "el_processor.h"
     20#include <complex>
     21#include <cmath>
     22#include <vector>
     23#include "fftw3.h"
     24
     25#define FILTERED_LFE
     26
     27#pragma comment (lib,"libfftw3f-3.lib")
     28
     29typedef std::complex<float> cfloat;
     30
     31const float PI = 3.141592654;
     32const float epsilon = 0.000001;
     33//const float center_level = 0.5*sqrt(0.5);   // gain of the center channel
     34const float center_level = sqrt(0.5);   // gain of the center channel
     35//const float center_level = 0.5;   // gain of the center channel
     36
     37// should be .6-.7
     38// but with centerlevel 2x what its supposed to be, we halve 0.68
     39// to keep center from clipping
     40const float window_gain = 0.34;     
     41
     42// private implementation of the surround decoder
     43class decoder_impl {
     44public:
     45    // create an instance of the decoder
     46    //  blocksize is fixed over the lifetime of this object for performance reasons
     47    decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
     48        // create FFTW buffers
     49        lt = (float*)fftwf_malloc(sizeof(float)*N);
     50        rt = (float*)fftwf_malloc(sizeof(float)*N);
     51        dst = (float*)fftwf_malloc(sizeof(float)*N);
     52        dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     53        dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     54        src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     55        loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE);
     56        loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE);
     57        store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE);   
     58        // resize our own buffers
     59        frontR.resize(N);
     60        frontL.resize(N);
     61        avg.resize(N);
     62        surR.resize(N);
     63        surL.resize(N);
     64#ifdef FILTERED_LFE
     65        trueavg.resize(N);
     66#endif
     67        xfs.resize(N);
     68        yfs.resize(N);
     69        inbuf[0].resize(N);
     70        inbuf[1].resize(N);
     71        for (unsigned c=0;c<6;c++) {
     72            outbuf[c].resize(N);
     73            filter[c].resize(N);
     74        }
     75        // DC component of filters is always 0
     76        for (unsigned c=0;c<5;c++)
     77        {
     78            filter[c][0] = 0.0;
     79            filter[c][1] = 0.0;
     80            filter[c][halfN] = 0.0;
     81        }
     82        sample_rate(48000);
     83        // generate the window function (square root of hann, b/c it is applied before and after the transform)
     84        wnd.resize(N);
     85        // dft normalization included in the window for zero cost scaling
     86        // also add a gain factor of *2 due to processing gain in algo (see center_level)
     87        for (unsigned k=0;k<N;k++)
     88            //wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
     89            wnd[k] = sqrt(window_gain*0.5*(1-cos(2*PI*k/N))/N);
     90        current_buf = 0;
     91        // set the default coefficients
     92        surround_coefficients(0.8165,0.5774);
     93        phase_mode(0);
     94        separation(1,1);
     95        steering_mode(1);
     96    }
     97
     98    // destructor
     99    ~decoder_impl() {
     100        // clean up the FFTW stuff
     101        fftwf_destroy_plan(store);
     102        fftwf_destroy_plan(loadR);
     103        fftwf_destroy_plan(loadL);
     104        fftwf_free(src);
     105        fftwf_free(dftR);
     106        fftwf_free(dftL);
     107        fftwf_free(dst);
     108        fftwf_free(rt);
     109        fftwf_free(lt);
     110    }
     111
     112    float ** getInputBuffers()
     113    {
     114        inbufs[0] = &inbuf[0][current_buf*halfN];
     115        inbufs[1] = &inbuf[1][current_buf*halfN];
     116        return inbufs;
     117    }
     118
     119    float ** getOutputBuffers()
     120    {
     121        outbufs[0] = &outbuf[0][current_buf*halfN];
     122        outbufs[1] = &outbuf[1][current_buf*halfN];
     123        outbufs[2] = &outbuf[2][current_buf*halfN];
     124        outbufs[3] = &outbuf[3][current_buf*halfN];
     125        outbufs[4] = &outbuf[4][current_buf*halfN];
     126        outbufs[5] = &outbuf[5][current_buf*halfN];
     127        return outbufs;
     128    }
     129
     130    // decode a chunk of stereo sound, has to contain exactly blocksize samples
     131    //  center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution
     132    //  dimension [0..1] moves the soundfield backwards, 0=front, 1=side
     133    //  adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption
     134    void decode(float center_width, float dimension, float adaption_rate) {
     135        // process first part
     136        int index;
     137        index = current_buf*halfN;
     138        float *in_second[2] = {&inbuf[0][index],&inbuf[1][index]};
     139        current_buf ^= 1;
     140        index = current_buf*halfN;
     141        float *in_first[2] = {&inbuf[0][index],&inbuf[1][index]};
     142        add_output(in_first,in_second,center_width,dimension,adaption_rate,true);
     143        // shift last half of input buffer to the beginning
     144    }
     145   
     146    // flush the internal buffers
     147    void flush() {
     148        for (unsigned k=0;k<N;k++) {
     149            for (unsigned c=0;c<6;c++)
     150                outbuf[c][k] = 0;
     151            inbuf[0][k] = 0;
     152            inbuf[1][k] = 0;
     153        }
     154    }
     155
     156    // set lfe filter params
     157    void sample_rate(unsigned int srate) {
     158        // lfe filter is just straight through band limited
     159        unsigned int cutoff = (250*N)/srate;
     160        for (unsigned f=0;f<=halfN;f++) {           
     161            if ((f>=2) && (f<cutoff))
     162                filter[5][f] = 1.0;
     163            else
     164                filter[5][f] = 0.0;
     165        }
     166    }
     167
     168    // set the assumed surround mixing coefficients
     169    void surround_coefficients(float a, float b) {
     170        master_gain = 1.0;
     171        // calc the simple coefficients
     172        surround_high = a;
     173        surround_low = b;
     174        surround_balance = (a-b)/(a+b);
     175        surround_level = 1/(a+b);
     176        // calc the linear coefficients
     177        cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0);
     178        A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n;
     179        E = (o+v)*n; F = (o+u)*n; G = (o-v)*n;  H = (o-u)*n;
     180    }
     181
     182    // set the phase shifting mode
     183    void phase_mode(unsigned mode) {
     184        const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}};
     185        phase_offsetL = modes[mode][0];
     186        phase_offsetR = modes[mode][1];
     187    }
     188
     189    // what steering mode should be chosen
     190    void steering_mode(bool mode) { linear_steering = mode; }
     191
     192    // set front & rear separation controls
     193    void separation(float front, float rear) {
     194        front_separation = front;
     195        rear_separation = rear;
     196    }
     197
     198private:
     199    // polar <-> cartesian coodinates conversion
     200    static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); }
     201    static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); }
     202    static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); }
     203    static inline float sqr(float x) { return x*x; }
     204    // the dreaded min/max
     205    static inline float min(float a, float b) { return a<b?a:b; }
     206    static inline float max(float a, float b) { return a>b?a:b; }
     207    static inline float clamp(float x) { return max(-1,min(1,x)); }
     208
     209    // handle the output buffering for overlapped calls of block_decode
     210    void add_output(float *input1[2], float *input2[2], float center_width, float dimension, float adaption_rate, bool result=false) {
     211        // add the windowed data to the last 1/2 of the output buffer
     212        float *out[6] = {&outbuf[0][0],&outbuf[1][0],&outbuf[2][0],&outbuf[3][0],&outbuf[4][0],&outbuf[5][0]};
     213        block_decode(input1,input2,out,center_width,dimension,adaption_rate);
     214    }
     215
     216    // CORE FUNCTION: decode a block of data
     217    void block_decode(float *input1[2], float *input2[2], float *output[6], float center_width, float dimension, float adaption_rate) {
     218        // 1. scale the input by the window function; this serves a dual purpose:
     219        // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed
     220        // - second it allows for smooth blending of varying filters between the blocks
     221        {
     222            float* pWnd = &wnd[0];
     223            float* pLt = &lt[0];
     224            float* pRt = &rt[0];
     225            float* pIn0 = input1[0];
     226            float* pIn1 = input1[1];
     227            for (unsigned k=0;k<halfN;k++) {
     228                *pLt++ = *pIn0++ * *pWnd;
     229                *pRt++ = *pIn1++ * *pWnd++;
     230            }
     231            pIn0 = input2[0];
     232            pIn1 = input2[1];
     233            //for (unsigned k=0,k1=halfN;k<halfN;k++,k1++) {
     234            for (unsigned k=0;k<halfN;k++) {
     235                *pLt++ = *pIn0++ * *pWnd;
     236                *pRt++ = *pIn1++ * *pWnd++;
     237            }
     238        }
     239
     240        // ... and tranform it into the frequency domain
     241        fftwf_execute(loadL);
     242        fftwf_execute(loadR);
     243
     244        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
     245        //    but dont do DC or N/2 component
     246        for (unsigned f=2;f<halfN;f++) {           
     247            // get left/right amplitudes/phases
     248            float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
     249            float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
     250//          if (ampL+ampR < epsilon)
     251//              continue;       
     252
     253            // calculate the amplitude/phase difference
     254            float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
     255            float phaseDiff = phaseL - phaseR;
     256            if (phaseDiff < -PI) phaseDiff += 2*PI;
     257            if (phaseDiff > PI) phaseDiff -= 2*PI;
     258            phaseDiff = abs(phaseDiff);
     259
     260            if (linear_steering) {
     261/*              cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);
     262                cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w;              */
     263//              xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();
     264//              yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);
     265
     266                /*
     267                Problem:
     268                This assumes that the values are interpolated linearly between the cardinal points.
     269                But this way we have no chance of knowing the average volume...
     270                - Can we solve that computing everything under the assumption of normalized volume?
     271                  No. Seemingly not.
     272                - Maybe we should add w explitcitly into the equation and see if we can solve it...
     273                */
     274
     275
     276                //cfloat lt(0.5,0),rt(0.5,0);
     277                //cfloat x(0,0), y(1,0);
     278                /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);
     279                cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);
     280                cfloat s = sqrt(p*p/4.0f - q);
     281                cfloat x = -p;
     282                cfloat x1 = -p/2.0f + s;
     283                cfloat x2 = -p/2.0f - s;
     284                float x = 0;
     285                if (x1.real() >= -1 && x1.real() <= 1)
     286                    x = x1.real();
     287                else if (x2.real() >= -1 && x2.real() <= 1)
     288                    x = x2.real();*/
     289
     290                //cfloat yp = (rt - (x*E+H))/(F+x*G);
     291                //cfloat xp = (lt - (y*B+D))/(A+y*C);
     292
     293                /*xfs[f] = x;
     294                yfs[f] = y.real();*/
     295
     296                // --- this is the fancy new linear mode ---
     297
     298                // get sound field x/y position
     299                yfs[f] = get_yfs(ampDiff,phaseDiff);
     300                xfs[f] = get_xfs(ampDiff,yfs[f]);
     301
     302                // add dimension control
     303                yfs[f] = clamp(yfs[f] - dimension);
     304
     305                // add crossfeed control
     306                xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
     307
     308                // 3. generate frequency filters for each output channel
     309                float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
     310                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
     311                float volume[5] = {
     312                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),  // left
     313                    front * center_level*((1-abs(xfs[f])) * (1-center_width)),          // center
     314                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right
     315                    back * surround_level * left,                                       // left surround
     316                    back * surround_level * right                                       // right surround
     317                };
     318
     319                // adapt the prior filter
     320                for (unsigned c=0;c<5;c++)
     321                    filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/*/N*/;
     322
     323            } else {
     324                // --- this is the old & simple steering mode ---
     325
     326                // calculate the amplitude/phase difference
     327                float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
     328                float phaseDiff = phaseL - phaseR;
     329                if (phaseDiff < -PI) phaseDiff += 2*PI;
     330                if (phaseDiff > PI) phaseDiff -= 2*PI;
     331                phaseDiff = abs(phaseDiff);
     332
     333                // determine sound field x-position
     334                xfs[f] = ampDiff;
     335
     336                // determine preliminary sound field y-position from phase difference
     337                yfs[f] = 1 - (phaseDiff/PI)*2;
     338
     339                if (abs(xfs[f]) > surround_balance) {
     340                    // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance
     341                    // this is necessary because the sound field is trapezoidal and will be stretched behind the listener
     342                    float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance);
     343                    yfs[f]  = (1-frontness) * yfs[f] + frontness * 1;
     344                }
     345
     346                // add dimension control
     347                yfs[f] = clamp(yfs[f] - dimension);
     348
     349                // add crossfeed control
     350                xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
     351
     352                // 3. generate frequency filters for each output channel, according to the signal position
     353                // the sum of all channel volumes must be 1.0
     354                float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
     355                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
     356                float volume[5] = {
     357                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),      // left
     358                    front * center_level*((1-abs(xfs[f])) * (1-center_width)),              // center
     359                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)),     // right
     360                    back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))),  // left surround
     361                    back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2)))   // right surround
     362                };
     363
     364                // adapt the prior filter
     365                for (unsigned c=0;c<5;c++)
     366                    filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/*/N*/;
     367            }
     368
     369            // ... and build the signal which we want to position
     370            frontL[f] = polar(ampL+ampR,phaseL);
     371            frontR[f] = polar(ampL+ampR,phaseR);
     372            avg[f] = frontL[f] + frontR[f];
     373            surL[f] = polar(ampL+ampR,phaseL+phase_offsetL);
     374            surR[f] = polar(ampL+ampR,phaseR+phase_offsetR);
     375#ifdef FILTERED_LFE
     376            trueavg[f] = cfloat(dftL[f][0] + dftR[f][0], dftL[f][1] + dftR[f][1]);
     377#endif
     378        }
     379
     380        // 4. distribute the unfiltered reference signals over the channels
     381        apply_filter(&frontL[0],&filter[0][0],&output[0][0]);   // front left
     382        apply_filter(&avg[0], &filter[1][0],&output[1][0]);     // front center
     383        apply_filter(&frontR[0],&filter[2][0],&output[2][0]);   // front right
     384        apply_filter(&surL[0],&filter[3][0],&output[3][0]);     // surround left
     385        apply_filter(&surR[0],&filter[4][0],&output[4][0]);     // surround right
     386#ifdef FILTERED_LFE
     387        apply_filter(&trueavg[0],&filter[5][0],&output[5][0]);  // lfe
     388#else
     389        float* out5 = &output[5][(current_buf)*halfN];
     390        float* in2l = &input2[0][0];
     391        float* in2r = &input2[1][0];
     392        //for (unsigned k=0,k2=N/4;k<halfN;k++,k2++) {
     393        for (unsigned k=0;k<halfN;k++) {
     394            *out5++ = *in2l++ + *in2r++;
     395        }
     396#endif
     397    }
     398
     399#define FASTER_CALC
     400    // map from amplitude difference and phase difference to yfs
     401    inline double get_yfs(double ampDiff, double phaseDiff) {
     402        double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2);
     403#ifdef FASTER_CALC
     404        double tanX = tan(x);
     405        return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
     406            + 0.09170680403453149*x*x*x + 0.2617754892323973*tanX - 0.04180413533856156*sqr(tanX);
     407#else
     408        return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
     409            + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x));
     410#endif
     411    }
     412
     413    // map from amplitude difference and yfs to xfs
     414    inline double get_xfs(double ampDiff, double yfs) {
     415        double x=ampDiff,y=yfs;
     416#ifdef FASTER_CALC
     417        double tanX = tan(x);
     418        double tanY = tan(y);
     419        double asinX = asin(x);
     420        double sinX = sin(x);
     421        double sinY = sin(y);
     422        double x3 = x*x*x;
     423        double y2 = y*y;
     424        double y3 = y*y2;
     425        return 2.464833559224702*x - 423.52131153259404*x*y +
     426            67.8557858606918*x3*y + 788.2429425544392*x*y2 -
     427            79.97650354902909*x3*y2 - 513.8966153850349*x*y3 +
     428            35.68117670186306*x3*y3 + 13867.406173420834*y*asinX -
     429            2075.8237075786396*y2*asinX - 908.2722068360281*y3*asinX -
     430            12934.654772878019*asinX*sinY - 13216.736529661162*y*tanX +
     431            1288.6463247741938*y2*tanX + 1384.372969378453*y3*tanX +
     432            12699.231471126128*sinY*tanX + 95.37131275594336*sinX*tanY -
     433            91.21223198407546*tanX*tanY;
     434#else
     435        return 2.464833559224702*x - 423.52131153259404*x*y +
     436            67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y -
     437            79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y +
     438            35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) -
     439            2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) -
     440            12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) +
     441            1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) +
     442            12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) -
     443            91.21223198407546*tan(x)*tan(y);
     444#endif
     445    }
     446
     447    // filter the complex source signal and add it to target
     448    void apply_filter(cfloat *signal, float *flt, float *target) {
     449        // filter the signal
     450        for (unsigned f=0;f<=halfN;f++) {       
     451            src[f][0] = signal[f].real() * flt[f];
     452            src[f][1] = signal[f].imag() * flt[f];
     453        }
     454        // transform into time domain
     455        fftwf_execute(store);
     456
     457        float* pT1   = &target[current_buf*halfN];
     458        float* pWnd1 = &wnd[0];
     459        float* pDst1 = &dst[0];
     460        float* pT2   = &target[(current_buf^1)*halfN];
     461        float* pWnd2 = &wnd[halfN];
     462        float* pDst2 = &dst[halfN];
     463        // add the result to target, windowed
     464        for (unsigned int k=0;k<halfN;k++)
     465        {
     466            // 1st part is overlap add
     467            *pT1++ += *pWnd1++ * *pDst1++;
     468            // 2nd part is set as has no history
     469            *pT2++ = *pWnd2++ * *pDst2++;
     470        }
     471    }
     472
     473    unsigned int N;                    // the block size
     474    unsigned int halfN;                // half block size precalculated
     475    // FFTW data structures
     476    float *lt,*rt,*dst;                // left total, right total (source arrays), destination array
     477    fftwf_complex *dftL,*dftR,*src;    // intermediate arrays (FFTs of lt & rt, processing source)
     478    fftwf_plan loadL,loadR,store;      // plans for loading the data into the intermediate format and back
     479    // buffers
     480    std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain
     481#ifdef FILTERED_LFE
     482    std::vector<cfloat> trueavg;       // for lfe generation
     483#endif
     484    std::vector<float> xfs,yfs;        // the feature space positions for each frequency bin
     485    std::vector<float> wnd;            // the window function, precalculated
     486    std::vector<float> filter[6];      // a frequency filter for each output channel
     487    std::vector<float> inbuf[2];       // the sliding input buffers
     488    std::vector<float> outbuf[6];      // the sliding output buffers
     489    // coefficients
     490    float surround_high,surround_low;  // high and low surround mixing coefficient (e.g. 0.8165/0.5774)
     491    float surround_balance;            // the xfs balance that follows from the coeffs
     492    float surround_level;              // gain for the surround channels (follows from the coeffs
     493    float master_gain;                 // gain for all channels
     494    float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels
     495    float front_separation;            // front stereo separation
     496    float rear_separation;             // rear stereo separation
     497    bool linear_steering;              // whether the steering should be linear or not
     498    cfloat A,B,C,D,E,F,G,H;            // coefficients for the linear steering
     499    int current_buf;                   // specifies which buffer is 2nd half of input sliding buffer
     500    float * inbufs[2];                 // for passing back to driver
     501    float * outbufs[6];                // for passing back to driver
     502
     503    friend class fsurround_decoder;
     504};
     505
     506
     507// implementation of the shell class
     508
     509fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { }
     510
     511fsurround_decoder::~fsurround_decoder() { delete impl; }
     512
     513void fsurround_decoder::decode(float center_width, float dimension, float adaption_rate) {
     514    impl->decode(center_width,dimension,adaption_rate);
     515}
     516
     517void fsurround_decoder::flush() { impl->flush(); }
     518
     519void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); }
     520
     521void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); }
     522
     523void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); }
     524
     525void fsurround_decoder::separation(float front, float rear) { impl->separation(front,rear); }
     526
     527float ** fsurround_decoder::getInputBuffers()
     528{
     529    return impl->getInputBuffers();
     530}
     531
     532float ** fsurround_decoder::getOutputBuffers()
     533{
     534    return impl->getOutputBuffers();
     535}
     536
     537void fsurround_decoder::sample_rate(unsigned int samplerate)
     538{
     539    impl->sample_rate(samplerate);
     540}
  • libs/libmythfreesurround/el_processor.h

     
     1/*
     2Copyright (C) 2007 Christian Kothe
     3
     4This program is free software; you can redistribute it and/or
     5modify it under the terms of the GNU General Public License
     6as published by the Free Software Foundation; either version 2
     7of the License, or (at your option) any later version.
     8
     9This program is distributed in the hope that it will be useful,
     10but WITHOUT ANY WARRANTY; without even the implied warranty of
     11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12GNU General Public License for more details.
     13
     14You should have received a copy of the GNU General Public License
     15along with this program; if not, write to the Free Software
     16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     17*/
     18
     19#ifndef EL_PROCESSOR_H
     20#define EL_PROCESSOR_H
     21
     22// the Free Surround decoder
     23class fsurround_decoder {
     24public:
     25        // create an instance of the decoder
     26        //  blocksize is fixed over the lifetime of this object for performance reasons
     27        fsurround_decoder(unsigned blocksize=8192);
     28        // destructor
     29        ~fsurround_decoder();
     30       
     31    float ** getInputBuffers();
     32    float ** getOutputBuffers();
     33
     34        // decode a chunk of stereo sound, has to contain exactly blocksize samples
     35        //  center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution
     36        //  dimension [0..1] moves the soundfield backwards, 0=front, 1=side
     37        //  adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption
     38        //void decode(float *input[2], float *output[6], float center_width=1, float dimension=0, float adaption_rate=1);       
     39        void decode(float center_width=1, float dimension=0, float adaption_rate=1);   
     40       
     41        // flush the internal buffers
     42        void flush();
     43
     44        // --- advanced configuration ---
     45
     46        // override the surround coefficients
     47        //  a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right.
     48        void surround_coefficients(float a, float b);
     49
     50        // set the phase shifting mode for decoding
     51        // 0 = (+0°,+0°)   - music mode
     52        // 1 = (+0°,+180°) - PowerDVD compatibility
     53        // 2 = (+180°,+0°) - BeSweet compatibility
     54        // 3 = (-90°,+90°) - This seems to work. I just don't know why.
     55        void phase_mode(unsigned mode);
     56
     57        // override the steering mode
     58        //  false = simple non-linear steering (old)
     59        //  true  = advanced linear steering (new)
     60        void steering_mode(bool mode);
     61
     62        // set front/rear stereo separation
     63        //  1.0 is default, 0.0 is mono
     64        void separation(float front,float rear);
     65
     66    // set samplerate for lfe filter
     67    void sample_rate(unsigned int samplerate);
     68
     69private:
     70        class decoder_impl *impl; // private implementation (details hidden)
     71};
     72
     73
     74#endif
  • libs/libmythfreesurround/freesurround.cpp

     
     1/*
     2Copyright (C) 2007 Christian Kothe, Mark Spieth
     3
     4This program is free software; you can redistribute it and/or
     5modify it under the terms of the GNU General Public License
     6as published by the Free Software Foundation; either version 2
     7of the License, or (at your option) any later version.
     8
     9This program is distributed in the hope that it will be useful,
     10but WITHOUT ANY WARRANTY; without even the implied warranty of
     11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12GNU General Public License for more details.
     13
     14You should have received a copy of the GNU General Public License
     15along with this program; if not, write to the Free Software
     16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     17*/
     18
     19#include <cstdio>
     20#include <cstdlib>
     21#include <cerrno>
     22#include <iostream>
     23#include <sstream>
     24//#include "compat.h"
     25#include "freesurround.h"
     26#include "el_processor.h"
     27#include <vector>
     28#include <list>
     29#include <map>
     30#include <math.h>
     31
     32#include <qstring.h>
     33#include <qdatetime.h>
     34
     35using namespace std;
     36
     37#if 0
     38#define VERBOSE(args...) \
     39    do { \
     40        QDateTime dtmp = QDateTime::currentDateTime(); \
     41        QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \
     42        ostringstream verbose_macro_tmp; \
     43        verbose_macro_tmp << dtime << " " << args; \
     44        cout << verbose_macro_tmp.str() << endl; \
     45    } while (0)
     46#else
     47#define VERBOSE(args...)
     48#endif
     49#if 0
     50#define VERBOSE1(args...) \
     51    do { \
     52        QDateTime dtmp = QDateTime::currentDateTime(); \
     53        QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \
     54        ostringstream verbose_macro_tmp; \
     55        verbose_macro_tmp << dtime << " " << args; \
     56        cout << verbose_macro_tmp.str() << endl; \
     57    } while (0)
     58#else
     59#define VERBOSE1(args...)
     60#endif
     61
     62// our default internal block size, in floats
     63const unsigned default_block_size = 8192;
     64// there will be a slider for this in the future
     65//const float master_gain = 1.0;
     66//#define MASTER_GAIN * master_gain
     67#define MASTER_GAIN
     68//const float master_gain = 1.0/(1<<15);
     69//const float inv_master_gain = (1<<15);
     70//#define INV_MASTER_GAIN * inv_master_gain
     71#define INV_MASTER_GAIN
     72
     73unsigned int block_size = default_block_size;
     74
     75// stupidity countermeasure...
     76template<class T> T pop_back(std::list<T> &l)
     77{
     78    T result(l.back());
     79    l.pop_back();
     80    return result;
     81}
     82
     83// a pool, where the DSP can throw its objects at after it got deleted and get them back when it is recreated...
     84class object_pool
     85{
     86public:
     87        typedef void* (*callback)();
     88        // initialize
     89        object_pool(callback cbf):construct(cbf) { }
     90        ~object_pool()
     91    {
     92                for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();i!=e;i++)
     93                        delete i->second;
     94                for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();i!=e;i++)
     95                        delete *i;
     96        }
     97        // (re)acquire an object
     98        void *acquire(void *who)
     99    {
     100                std::map<void*,void*>::iterator i(pool.find(who));
     101                if (i != pool.end())
     102                        return i->second;
     103                else
     104                        if (!freelist.empty())
     105                                return pool.insert(std::make_pair(who,pop_back(freelist))).first->second;
     106                        else
     107                                return pool.insert(std::make_pair(who,construct())).first->second;
     108        }
     109        // release an object into the wild
     110        void release(void *who)
     111    {
     112                std::map<void*,void*>::iterator i(pool.find(who));
     113                if (i != pool.end()) {
     114                        freelist.push_back(i->second);
     115                        pool.erase(i);
     116                }
     117        }       
     118public:
     119        callback construct;                     // object constructor callback
     120        std::list<void*> freelist;              // list of available objects
     121        std::map<void*,void*> pool;     // pool of used objects, by class
     122};
     123
     124// buffers which we usually need (and want to share between plugin lifespans)
     125struct buffers
     126{
     127        buffers(unsigned int s):
     128        //lt(s),rt(s),
     129        l(s),r(s),c(s),ls(s),rs(s),lfe(s) { }
     130        void resize(unsigned int s)
     131    {
     132                //lt.resize(s); rt.resize(s);
     133        l.resize(s); r.resize(s); lfe.resize(s);
     134                ls.resize(s); rs.resize(s); c.resize(s);
     135        }
     136        void clear()
     137    {
     138                //lt.clear(); rt.clear();
     139        l.clear(); r.clear(); lfe.clear();
     140                ls.clear(); rs.clear(); c.clear();
     141        }
     142        //std::vector<float> lt,rt;                                             // for multiplexing
     143        std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs;  // for demultiplexing
     144};
     145
     146struct int16buffers
     147{
     148        int16buffers(unsigned int s):
     149        l(s),r(s),c(s),ls(s),rs(s),lfe(s) { }
     150        void resize(unsigned int s)
     151    {
     152                l.resize(s); r.resize(s); lfe.resize(s);
     153                ls.resize(s); rs.resize(s); c.resize(s);
     154        }
     155        void clear()
     156    {
     157                l.clear(); r.clear();
     158                ls.clear(); rs.clear(); c.clear();
     159        lfe.clear();
     160        }
     161        std::vector<short> l,r,c,ls,rs,lfe;     // for demultiplexing
     162};
     163
     164// construction methods
     165void *new_decoder() { return new fsurround_decoder(block_size); }
     166void *new_buffers() { return new buffers(block_size/2); }
     167void *new_int16buffers() { return new int16buffers(block_size/2); }
     168
     169object_pool dp(&new_decoder);
     170//object_pool bp(&new_buffers);
     171object_pool bp16(&new_int16buffers);
     172
     173//#define SPEAKERTEST
     174#ifdef SPEAKERTEST
     175int channel_select = -1;
     176#endif
     177
     178FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) :
     179        srate(srate),
     180        open_(false),
     181        initialized_(false),
     182        //bufs(NULL),
     183        int16bufs(NULL),
     184        decoder(0),
     185        in_count(0),
     186        out_count(0),
     187        processed(true),
     188        surround_mode(smode)
     189{
     190    VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode));
     191    if (moviemode)
     192    {
     193        params.phasemode = 1;
     194        params.center_width = 0;
     195    }
     196    else
     197    {
     198        params.center_width = 50;
     199    }
     200    switch (surround_mode)
     201    {
     202        case SurroundModeActiveSimple:
     203            params.steering = 0;
     204            //bufs = (buffers*)bp.acquire((void*)1);
     205            break;
     206        case SurroundModeActiveLinear:
     207            params.steering = 1;
     208            //bufs = (buffers*)bp.acquire((void*)1);
     209            break;
     210        default:
     211            //int16bufs = (int16buffers*)bp16.acquire((void*)1);
     212            break;
     213    }
     214    int16bufs = (int16buffers*)bp16.acquire((void*)1);
     215    open();
     216#ifdef SPEAKERTEST
     217    channel_select++;
     218    if (channel_select>=6)
     219        channel_select = 0;
     220    VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select));
     221#endif
     222
     223    VERBOSE(QString("FreeSurround::FreeSurround done"));
     224}
     225
     226void FreeSurround::SetParams()
     227{
     228    if (decoder)
     229    {
     230        decoder->steering_mode(params.steering);
     231        decoder->phase_mode(params.phasemode);
     232        decoder->surround_coefficients(params.coeff_a, params.coeff_b);                         
     233        decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
     234    }
     235}
     236
     237FreeSurround::fsurround_params::fsurround_params(
     238        int32_t center_width,
     239        int32_t dimension
     240    ) :
     241    center_width(center_width),
     242    dimension(dimension),
     243    coeff_a(0.8165),coeff_b(0.5774),
     244    phasemode(0),
     245    steering(1),
     246    front_sep(100),
     247    rear_sep(100)
     248{
     249}
     250
     251FreeSurround::~FreeSurround()
     252{
     253    VERBOSE(QString("FreeSurround::~FreeSurround"));
     254    close();
     255    /*
     256    if (bufs)
     257    {
     258        bp.release((void*)1);
     259        bufs = NULL;
     260    }
     261    */
     262    if (int16bufs)
     263    {
     264        bp16.release((void*)1);
     265        int16bufs = NULL;
     266    }
     267    VERBOSE(QString("FreeSurround::~FreeSurround done"));
     268}
     269
     270void get_peak_i(short* data, int count, int* maxv, int* minv)
     271{
     272    int _maxv = *data++;
     273    int _minv = _maxv;
     274    for(int i=1;i<count;i++)
     275    {
     276        int v = *data++;
     277        if (v > _maxv) _maxv = v;
     278        if (v < _minv) _minv = v;
     279    }
     280    *maxv = _maxv;
     281    *minv = _minv;
     282}
     283
     284void get_peak_i2(short* data, int count, int* maxv, int* minv)
     285{
     286    int _maxv = *data;
     287    data += 2;
     288    int _minv = _maxv;
     289    for(int i=1;i<count;i++)
     290    {
     291        int v = *data;
     292        if (v > _maxv) _maxv = v;
     293        if (v < _minv) _minv = v;
     294        data  += 2;
     295    }
     296    *maxv = _maxv;
     297    *minv = _minv;
     298}
     299
     300void get_peak(float* data, int count, int* maxv, int* minv)
     301{
     302    int _maxv = lrintf(*data++);
     303    int _minv = _maxv;
     304    for(int i=1;i<count;i++)
     305    {
     306        int v = lrintf(*data++);
     307        if (v > _maxv) _maxv = v;
     308        if (v < _minv) _minv = v;
     309    }
     310    *maxv = _maxv;
     311    *minv = _minv;
     312}
     313
     314uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step)
     315{
     316    int i;
     317    int ic = in_count;
     318    int bs = block_size/2;
     319    bool process = true;
     320    // demultiplex
     321    switch (surround_mode)
     322    {
     323        case SurroundModePassive:
     324            switch (numChannels)
     325            {
     326                case 1:
     327                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     328                    {
     329                        int16bufs->l[ic] =
     330                        int16bufs->c[ic] =
     331                        int16bufs->r[ic] =
     332                            samples[i] >> 1;
     333                    }
     334                    break;
     335                case 2:
     336                    if (step>0)
     337                    {
     338                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     339                        {
     340                            short lt = samples[i] >> 1;
     341                            short rt = samples[i+step] >> 1;
     342                            int16bufs->l[ic] = lt;
     343                            int16bufs->lfe[ic] =
     344                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     345                            int16bufs->r[ic] = rt;
     346                            int16bufs->ls[ic] =
     347                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     348                        }
     349                    }
     350                    else
     351                    {
     352                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     353                        {
     354                            short lt = samples[i*2] >> 1;
     355                            short rt = samples[i*2+1] >> 1;
     356                            int16bufs->l[ic] = lt;
     357                            int16bufs->lfe[ic] =
     358                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     359                            int16bufs->r[ic] = rt;
     360                            int16bufs->ls[ic] =
     361                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     362                        }
     363                    }
     364                    break;
     365                case 6:
     366                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     367                    {
     368                        int16bufs->l[ic] = *samples++ >> 1;
     369                        int16bufs->c[ic] = *samples++ >> 1;
     370                        int16bufs->r[ic] = *samples++ >> 1;
     371                        int16bufs->ls[ic] = *samples++ >> 1;
     372                        int16bufs->rs[ic] = *samples++ >> 1;
     373                        int16bufs->lfe[ic] = *samples++ >> 1;
     374                    }
     375                    break;
     376            }
     377            in_count = 0;
     378            out_count = ic;
     379            processed_size = ic;
     380            processed = false;
     381            break;
     382
     383        default:
     384            {
     385                float** inputs = decoder->getInputBuffers();
     386                float * lt = &inputs[0][ic];
     387                float * rt = &inputs[1][ic];
     388                if ((ic+numSamples) > bs)
     389                    numSamples = bs - ic;
     390                switch (numChannels)
     391                {
     392                    case 1:
     393                        for (i=0;i<numSamples;i++)
     394                        {
     395                            *lt++ =
     396                            *rt++ =
     397                                *samples++ MASTER_GAIN;
     398                        }
     399                        break;
     400                    case 2:
     401                        if (step>0)
     402                        {
     403                            for (i=0;i<numSamples;i++)
     404                            {
     405                                *lt++ = samples[0] MASTER_GAIN;
     406                                *rt++ = samples[step] MASTER_GAIN;
     407                                samples++;
     408                            }
     409                        }
     410                        else
     411                        {
     412                            for (i=0;i<numSamples;i++)
     413                            {
     414                                *lt++ = *samples++ MASTER_GAIN;
     415                                *rt++ = *samples++ MASTER_GAIN;
     416                            }
     417                        }
     418                        break;
     419                    case 6:
     420                        {
     421                        process = false;
     422                        short * l = &int16bufs->l[ic];
     423                        short * c = &int16bufs->c[ic];
     424                        short * r = &int16bufs->r[ic];
     425                        short * ls = &int16bufs->ls[ic];
     426                        short * rs = &int16bufs->rs[ic];
     427                        short * lfe = &int16bufs->lfe[ic];
     428                        for (i=0;i<numSamples;i++)
     429                        {
     430                            *l++ = *samples++ >> 1;
     431                            *c++ = *samples++ >> 1;
     432                            *r++ = *samples++ >> 1;
     433                            *ls++ = *samples++ >> 1;
     434                            *rs++ = *samples++ >> 1;
     435                            *lfe++ = *samples++ >> 1;
     436                        }
     437                        } break;
     438                }
     439                ic += numSamples;
     440                in_count = ic;
     441                processed = process;
     442                if (ic == bs)
     443                {
     444                    in_count = 0;
     445                    if (process)
     446                    {
     447                        process_block();
     448                    }
     449                    out_count = bs;
     450                    processed_size = bs;
     451                }
     452            } break;
     453    }
     454    VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5")
     455            .arg(numSamples)
     456            .arg(numChannels)
     457            .arg(step)
     458            .arg(i)
     459            .arg(out_count)
     460           );
     461    return i;
     462}
     463
     464uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step)
     465{
     466    int i;
     467    int ic = in_count;
     468    int bs = block_size/2;
     469    bool process = true;
     470    // demultiplex
     471    switch (surround_mode)
     472    {
     473        case SurroundModePassive:
     474            switch (numChannels)
     475            {
     476                case 1:
     477                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     478                    {
     479                        int16bufs->l[ic] =
     480                        int16bufs->c[ic] =
     481                        int16bufs->r[ic] =
     482                            samples[i] << 7;
     483                    }
     484                    break;
     485                case 2:
     486                    if (step>0)
     487                    {
     488                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     489                        {
     490                            short lt = samples[i] << 7;
     491                            short rt = samples[i+step] << 7;
     492                            int16bufs->l[ic] = lt;
     493                            int16bufs->lfe[ic] =
     494                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     495                            int16bufs->r[ic] = rt;
     496                            int16bufs->ls[ic] =
     497                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     498                        }
     499                    }
     500                    else
     501                    {
     502                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     503                        {
     504                            short lt = samples[i*2] << 7;
     505                            short rt = samples[i*2+1] << 7;
     506                            int16bufs->l[ic] = lt;
     507                            int16bufs->lfe[ic] =
     508                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     509                            int16bufs->r[ic] = rt;
     510                            int16bufs->ls[ic] =
     511                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     512                        }
     513                    }
     514                    break;
     515                case 6:
     516                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     517                    {
     518                        int16bufs->l[ic] = *samples++ << 7;
     519                        int16bufs->c[ic] = *samples++ << 7;
     520                        int16bufs->r[ic] = *samples++ << 7;
     521                        int16bufs->ls[ic] = *samples++ << 7;
     522                        int16bufs->rs[ic] = *samples++ << 7;
     523                        int16bufs->lfe[ic] = *samples++ << 7;
     524                    }
     525                    break;
     526            }
     527            in_count = 0;
     528            out_count = ic;
     529            processed_size = ic;
     530            processed = false;
     531            break;
     532
     533        default:
     534            {
     535                float** inputs = decoder->getInputBuffers();
     536                float * lt = &inputs[0][ic];
     537                float * rt = &inputs[1][ic];
     538                if ((ic+numSamples) > bs)
     539                    numSamples = bs - ic;
     540                switch (numChannels)
     541                {
     542                    case 1:
     543                        for (i=0;i<numSamples;i++)
     544                        {
     545                            *lt++ =
     546                            *rt++ =
     547                                *samples++ MASTER_GAIN;
     548                        }
     549                        break;
     550                    case 2:
     551                        if (step>0)
     552                        {
     553                            for (i=0;i<numSamples;i++)
     554                            {
     555                                *lt++ = samples[0] MASTER_GAIN;
     556                                *rt++ = samples[step] MASTER_GAIN;
     557                                samples++;
     558                            }
     559                        }
     560                        else
     561                        {
     562                            for (i=0;i<numSamples;i++)
     563                            {
     564                                *lt++ = *samples++ MASTER_GAIN;
     565                                *rt++ = *samples++ MASTER_GAIN;
     566                            }
     567                        }
     568                        break;
     569                    case 6:
     570                        {
     571                        process = false;
     572                        short * l = &int16bufs->l[ic];
     573                        short * c = &int16bufs->c[ic];
     574                        short * r = &int16bufs->r[ic];
     575                        short * ls = &int16bufs->ls[ic];
     576                        short * rs = &int16bufs->rs[ic];
     577                        short * lfe = &int16bufs->lfe[ic];
     578                        for (i=0;i<numSamples;i++)
     579                        {
     580                            *l++ = *samples++ << 7;
     581                            *c++ = *samples++ << 7;
     582                            *r++ = *samples++ << 7;
     583                            *ls++ = *samples++ << 7;
     584                            *rs++ = *samples++ << 7;
     585                            *lfe++ = *samples++ << 7;
     586                        }
     587                        } break;
     588                }
     589                ic += numSamples;
     590                in_count = ic;
     591                processed = process;
     592                if (ic == bs)
     593                {
     594                    in_count = 0;
     595                    if (process)
     596                        process_block();
     597                    out_count = bs;
     598                    processed_size = bs;
     599                }
     600            } break;
     601    }
     602    VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5")
     603            .arg(numSamples)
     604            .arg(numChannels)
     605            .arg(step)
     606            .arg(i)
     607            .arg(out_count)
     608           );
     609    return i;
     610}
     611
     612uint FreeSurround::receiveSamples(
     613        short *output,
     614        uint maxSamples
     615        )
     616{
     617    uint i;
     618    uint oc = out_count;
     619    if (maxSamples>oc) maxSamples = oc;
     620    uint outindex = processed_size - oc;
     621    switch (surround_mode)
     622    {
     623        case SurroundModePassive:
     624            for (unsigned int i=0;i<maxSamples;i++)
     625            {
     626                *output++ = int16bufs->l[outindex];
     627                *output++ = int16bufs->r[outindex];
     628                *output++ = int16bufs->ls[outindex];
     629                *output++ = int16bufs->rs[outindex];
     630                *output++ = int16bufs->c[outindex];
     631                *output++ = int16bufs->lfe[outindex];
     632                oc--;
     633                outindex++;
     634            }
     635            break;
     636
     637        default:
     638            if (processed)
     639            {
     640                float** outputs = decoder->getOutputBuffers();
     641                float * l = &outputs[0][outindex];
     642                float * c = &outputs[1][outindex];
     643                float * r = &outputs[2][outindex];
     644                float * ls = &outputs[3][outindex];
     645                float * rs = &outputs[4][outindex];
     646                float * lfe = &outputs[5][outindex];
     647                for (unsigned int i=0;i<maxSamples;i++)
     648                {
     649                    *output++ = lrintf(*l++ INV_MASTER_GAIN);
     650                    *output++ = lrintf(*r++ INV_MASTER_GAIN);
     651                    *output++ = lrintf(*ls++ INV_MASTER_GAIN);
     652                    *output++ = lrintf(*rs++ INV_MASTER_GAIN);
     653                    *output++ = lrintf(*c++ INV_MASTER_GAIN);
     654                    *output++ = lrintf(*lfe++ INV_MASTER_GAIN);
     655                }
     656                oc -= maxSamples;
     657                outindex += maxSamples;
     658            }
     659            else
     660            {
     661                short * l = &int16bufs->l[outindex];
     662                short * c = &int16bufs->c[outindex];
     663                short * r = &int16bufs->r[outindex];
     664                short * ls = &int16bufs->ls[outindex];
     665                short * rs = &int16bufs->rs[outindex];
     666                short * lfe = &int16bufs->lfe[outindex];
     667                for (unsigned int i=0;i<maxSamples;i++)
     668                {
     669                    *output++ = *l++;
     670                    *output++ = *r++;
     671                    *output++ = *ls++;
     672                    *output++ = *rs++;
     673                    *output++ = *c++;
     674                    *output++ = *lfe++;
     675                }
     676                oc -= maxSamples;
     677                outindex += maxSamples;
     678            }
     679            break;
     680    }
     681    out_count = oc;
     682    VERBOSE1(QString("FreeSurround::receiveSamples %1")
     683            .arg(maxSamples)
     684           );
     685    return maxSamples;
     686}
     687
     688void FreeSurround::process_block()
     689{
     690    // process the data
     691    try
     692    {
     693        if (decoder)
     694        {
     695            // actually these params need only be set when they change... but it doesn't hurt
     696#if 0
     697            decoder->steering_mode(params.steering);
     698            decoder->phase_mode(params.phasemode);
     699            decoder->surround_coefficients(params.coeff_a, params.coeff_b);                             
     700            decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
     701#endif
     702            // decode the bufs->block
     703            //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);
     704            //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);
     705            decoder->decode(params.center_width/100.0,params.dimension/100.0);
     706        }
     707    }
     708    catch(...)
     709    {
     710        //throw(std::runtime_error(std::string("error during processing (unsupported input format?)")));
     711    }
     712}
     713
     714long long FreeSurround::getLatency()
     715{
     716    // returns in usec
     717    if (surround_mode == SurroundModePassive)
     718        return 0;
     719    return decoder ? ((block_size/2 + in_count)*1000000)/(2*srate) : 0;
     720}
     721
     722void FreeSurround::flush()
     723{
     724    if (decoder)
     725        decoder->flush();
     726    int16bufs->clear();
     727}
     728
     729// load the lib and initialize the interface
     730void FreeSurround::open()
     731{               
     732    if (!decoder)
     733    {
     734        decoder = (fsurround_decoder*)dp.acquire((void*)1);
     735        decoder->flush();
     736        //if (bufs)
     737        //    bufs->clear();
     738        if (int16bufs)
     739            int16bufs->clear();
     740        decoder->sample_rate(srate);
     741    }
     742    SetParams();
     743}
     744
     745void FreeSurround::close()
     746{
     747    if (decoder)
     748    {
     749        dp.release(this);
     750        decoder = 0;
     751    }
     752}
     753
     754uint FreeSurround::numUnprocessedSamples()
     755{
     756    return in_count;
     757}
     758
     759uint FreeSurround::numSamples()
     760{
     761    return out_count;
     762}
     763
     764uint FreeSurround::sampleLatency()
     765{
     766    if (processed)
     767        return in_count + out_count + (block_size/2);
     768    else
     769        return in_count + out_count;
     770}
     771
     772uint FreeSurround::samplesPerBlock()
     773{
     774    return block_size/2;
     775}
     776
  • libs/libmythfreesurround/freesurround.h

     
     1/*
     2Copyright (C) 2007 Christian Kothe, Mark Spieth
     3
     4This program is free software; you can redistribute it and/or
     5modify it under the terms of the GNU General Public License
     6as published by the Free Software Foundation; either version 2
     7of the License, or (at your option) any later version.
     8
     9This program is distributed in the hope that it will be useful,
     10but WITHOUT ANY WARRANTY; without even the implied warranty of
     11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12GNU General Public License for more details.
     13
     14You should have received a copy of the GNU General Public License
     15along with this program; if not, write to the Free Software
     16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     17*/
     18
     19#ifndef FREESURROUND_H
     20#define FREESURROUND_H
     21
     22class FreeSurround
     23{
     24public:
     25    typedef enum
     26    {
     27        SurroundModePassive,
     28        SurroundModeActiveSimple,
     29        SurroundModeActiveLinear
     30    } SurroundMode;
     31public:
     32    FreeSurround(uint srate, bool moviemode, SurroundMode mode);
     33    ~FreeSurround();
     34
     35    // put samples in buffer, returns number of samples used
     36    uint putSamples(short* samples, uint numSamples, uint numChannels, int step);
     37    uint putSamples(char* samples, uint numSamples, uint numChannels, int step);
     38    // get a number of samples
     39    uint receiveSamples(short *output,
     40                        uint maxSamples
     41                        );
     42    // flush unprocessed samples
     43    void flush();
     44    //void setSampleRate(uint srate);
     45    uint numUnprocessedSamples();
     46    uint numSamples();
     47
     48    long long getLatency();
     49    uint sampleLatency();
     50
     51    uint samplesPerBlock();
     52
     53protected:
     54    void process_block();
     55    void open();
     56    void close();
     57    void SetParams();
     58
     59private:
     60
     61        // the changeable parameters
     62    struct fsurround_params {
     63        int32_t center_width;       // presence of the center channel
     64        int32_t dimension;                  // dimension
     65        float coeff_a,coeff_b;  // surround mixing coefficients
     66        int32_t phasemode;                      // phase shifting mode
     67        int32_t steering;                       // steering mode (0=simple, 1=linear)
     68        int32_t front_sep, rear_sep;// front/rear stereo separation
     69
     70        // (default) constructor
     71        fsurround_params(int32_t center_width=100, int32_t dimension=0);
     72    } params;
     73
     74        // additional settings
     75        uint srate;
     76
     77        // info about the current setup
     78        bool open_;                                     // whether a stream is currently open
     79        bool initialized_;                      // whether the thing is intialized     
     80        //struct buffers *bufs;                         // our buffers
     81        struct int16buffers *int16bufs;         // our buffers
     82        class fsurround_decoder *decoder;       // the surround decoder
     83    int in_count;               // amount in lt,rt
     84    int out_count;              // amount in output bufs
     85    bool processed;             // whether processing is enabled or not for latency calc
     86    int processed_size;         // amount processed
     87    SurroundMode surround_mode; // 1 of 3 surround modes supported
     88
     89};
     90
     91#endif
     92
  • libs/libmythfreesurround/libmythfreesurround.pro

     
     1include ( ../../config.mak )
     2include ( ../../settings.pro )
     3
     4TEMPLATE = lib
     5TARGET = mythfreesurround-$$LIBVERSION
     6CONFIG += thread staticlib warn_off
     7
     8INCLUDEPATH += ../../libs/libavcodec ../..
     9
     10#build position independent code since the library is linked into a shared library
     11QMAKE_CXXFLAGS += -fPIC -DPIC
     12
     13QMAKE_CLEAN += $(TARGET) $(TARGETA) $(TARGETD) $(TARGET0) $(TARGET1) $(TARGET2)
     14
     15# Input
     16HEADERS += el_processor.h
     17HEADERS += freesurround.h
     18
     19SOURCES += el_processor.cpp
     20SOURCES += freesurround.cpp
     21
     22#required until its rewritten to use avcodec fft lib
     23#LIBS += -lfftw3
     24LIBS += -lfftw3f
     25
  • libs/libs.pro

     
    77
    88# Directories
    99SUBDIRS += libavutil libavcodec libavformat libmythsamplerate
     10#SUBDIRS += libaf
    1011SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav
     12SUBDIRS += libmythfreesurround
    1113SUBDIRS += libmyth
    1214
    1315SUBDIRS += libmythupnp libmythui
  • libs/libmyth/libmyth.pro

     
    2525HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h
    2626HEADERS += mythhdd.h mythcdrom.h
    2727HEADERS += compat.h
     28HEADERS += audiooutputdigitalencoder.h
    2829
    2930SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
    3031SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
     
    4041SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp
    4142SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp
    4243SOURCES += mythhdd.cpp mythcdrom.cpp
     44SOURCES += audiooutputdigitalencoder.cpp
    4345
    4446INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./
     47INCLUDEPATH += ../libavutil
     48INCLUDEPATH += ../libmythfreesurround
    4549DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
    4650DEPENDPATH += ../libmythupnp
     51DEPENDPATH += ../libavutil ../libavcodec
     52DEPENDPATH += ../libmythfreesurround
    4753
    4854LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4955LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     56LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION}
     57LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION}
     58LIBS += -lfftw3f
    5059
    5160TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
    5261TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT}
     62TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT}
    5363
    5464inc.path = $${PREFIX}/include/mythtv/
    5565inc.files  = dialogbox.h lcddevice.h mythcontext.h mythdbcon.h
     
    207217use_hidesyms {
    208218    QMAKE_CXXFLAGS += -fvisibility=hidden
    209219}
     220
     221contains( CONFIG_LIBA52, yes ) {
     222    LIBS += -la52
     223}
  • 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
     39                             ) = 0;
    3640   
    3741    virtual void SetStretchFactor(float factor);
     42    virtual float GetStretchFactor();
    3843
    3944    // do AddSamples calls block?
    4045    virtual void SetBlocking(bool blocking) = 0;
     
    7479        lastError = msg;
    7580        VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError);
    7681    }
     82    void ClearError()
     83     { lastError = QString::null; };
    7784
    7885    void Warn(QString msg)
    7986    {
  • libs/libmyth/audiooutput.cpp

     
    133133{
    134134}
    135135
     136float AudioOutput::GetStretchFactor()
     137{
     138    return 1.0;
     139}
    136140
     141
     142
  • 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
     138                                )
    135139{
    136140    if (dsbuffer)
    137141        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();
    4862
    4963    virtual void Reset(void);
    5064
     
    125139    bool audio_passthru;
    126140
    127141    float audio_stretchfactor;
     142    AVCodecContext *audio_codec;
    128143    AudioOutputSource source;
    129144
    130145    bool killaudio;
     
    133148    bool set_initial_vol;
    134149    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    135150   
     151    int configured_audio_channels;
     152
    136153 private:
    137154    // resampler
    138155    bool need_resampler;
     
    144161
    145162    // timestretch
    146163    soundtouch::SoundTouch * pSoundStretch;
     164    AudioOutputDigitalEncoder * encoder;
     165    FreeSurround * upmixer;
    147166
     167    int source_audio_channels;
     168    int source_audio_bytes_per_sample;
     169    bool needs_upmix;
     170    int surround_mode;
     171
    148172    bool blocking; // do AddSamples calls block?
    149173
    150174    int lastaudiolen;
     
    162186
    163187    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    164188                                    'audiotime' and 'audiotime_updated' */
    165     int audiotime; // timecode of audio leaving the soundcard (same units as
     189    long long audiotime; // timecode of audio leaving the soundcard (same units as
    166190                   //                                          timecodes) ...
    167191    struct timeval audiotime_updated; // ... which was last updated at this time
    168192
    169193    /* Audio circular buffer */
    170194    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    171195    int raud, waud;     /* read and write positions */
    172     int audbuf_timecode;    /* timecode of audio most recently placed into
     196    long long audbuf_timecode;    /* timecode of audio most recently placed into
    173197                   buffer */
    174198
    175199    int numlowbuffer;
  • 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 + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     132                    encoder = new AudioOutputDigitalEncoder();
     133                    if (!encoder->Init(audio_codec->codec_id,
     134                                audio_codec->bit_rate,
     135                                audio_codec->sample_rate,
     136                                audio_codec->channels
     137                                ))
     138                    {
     139                        // eeks
     140                        delete encoder;
     141                        encoder = NULL;
     142                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     143                    }
     144                }
     145            }
     146            if (encoder)
     147            {
     148                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     149                pSoundStretch->setChannels(audio_codec->channels);
     150            }
     151            else
     152            {
     153                pSoundStretch->setSampleRate(audio_samplerate);
     154                pSoundStretch->setChannels(audio_channels);
     155            }
    116156
    117157            pSoundStretch->setTempo(audio_stretchfactor);
    118158            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    134174    pthread_mutex_unlock(&audio_buflock);
    135175}
    136176
     177float AudioOutputBase::GetStretchFactor()
     178{
     179    return audio_stretchfactor;
     180}
     181
    137182void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    138                                  int laudio_samplerate, bool laudio_passthru)
     183                                 int laudio_samplerate, bool laudio_passthru,
     184                                 void* laudio_codec)
    139185{
     186    int codec_id = CODEC_ID_NONE;
     187    int lcodec_id = CODEC_ID_NONE;
     188    int lcchannels = 0;
     189    int cchannels = 0;
     190    int lsource_audio_channels = laudio_channels;
     191    bool lneeds_upmix = false;
     192
     193    if (laudio_codec)
     194    {
     195        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     196        laudio_bits = 16;
     197        laudio_channels = 2;
     198        lsource_audio_channels = laudio_channels;
     199        laudio_samplerate = 48000;
     200        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     201    }
     202    if (audio_codec)
     203    {
     204        codec_id = audio_codec->codec_id;
     205        cchannels = ((AVCodecContext*)audio_codec)->channels;
     206    }
     207    if ((configured_audio_channels == 6) &&
     208        !(laudio_codec || audio_codec))
     209    {
     210        laudio_channels = configured_audio_channels;
     211        lneeds_upmix = true;
     212        VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     213    }
     214    ClearError();
    140215    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     216        laudio_samplerate == audio_samplerate && !need_resampler &&
     217        laudio_passthru == audio_passthru &&
     218        lneeds_upmix == needs_upmix &&
     219        lcodec_id == codec_id && lcchannels == cchannels)
     220    {
     221        VERBOSE(VB_AUDIO,LOC + "no change exiting");
    143222        return;
    144 
     223    }
    145224    KillAudio();
    146225   
    147226    pthread_mutex_lock(&audio_buflock);
     
    151230    waud = raud = 0;
    152231    audio_actually_paused = false;
    153232   
     233    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154234    audio_channels = laudio_channels;
     235    source_audio_channels = lsource_audio_channels;
    155236    audio_bits = laudio_bits;
    156237    audio_samplerate = laudio_samplerate;
     238    audio_codec = (AVCodecContext*)laudio_codec;
    157239    audio_passthru = laudio_passthru;
     240    needs_upmix = lneeds_upmix;
    158241    if (audio_bits != 8 && audio_bits != 16)
    159242    {
    160243        pthread_mutex_unlock(&avsync_lock);
     
    163246        return;
    164247    }
    165248    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     249    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    166250   
    167251    need_resampler = false;
    168252    killaudio = false;
     
    172256   
    173257    numlowbuffer = 0;
    174258
     259    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     260            .arg(audio_main_device).arg(audio_channels)
     261            .arg(source_audio_channels).arg(audio_samplerate));
     262 
    175263    // Actually do the device specific open call
    176264    if (!OpenDevice())
    177265    {
    178266        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179267        pthread_mutex_unlock(&avsync_lock);
    180268        pthread_mutex_unlock(&audio_buflock);
     269        if (GetError().isEmpty())
     270            Error("Aborting reconfigure");
     271        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181272        return;
    182273    }
    183274
     
    200291    current_seconds = -1;
    201292    source_bitrate = -1;
    202293
     294    // NOTE: this wont do anything as above samplerate vars are set equal
    203295    // Check if we need the resampler
    204296    if (audio_samplerate != laudio_samplerate)
    205297    {
     
    222314        need_resampler = true;
    223315    }
    224316
     317    if (needs_upmix)
     318    {
     319        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     320        if (configured_audio_channels == 6)
     321        {
     322            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
     323        }
     324        upmixer = new FreeSurround(audio_samplerate,
     325                                    source == AUDIOOUTPUT_VIDEO,
     326                                    (FreeSurround::SurroundMode)surround_mode);
     327        VERBOSE(VB_AUDIO, LOC + QString("create upmixer done with surround mode %1").arg(surround_mode));
     328    }
     329
    225330    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226331            .arg(audio_stretchfactor));
     332    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     333            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    227334
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     335    if (redo_stretch)
    230336    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     337        float laudio_stretchfactor = audio_stretchfactor;
     338        delete pSoundStretch;
     339        pSoundStretch = NULL;
     340        audio_stretchfactor = 0.0;
     341        SetStretchFactorLocked(laudio_stretchfactor);
    233342    }
     343    else
     344    {
     345        SetStretchFactorLocked(audio_stretchfactor);
     346        if (pSoundStretch)
     347        {
     348            // if its passthru then we need to reencode
     349            if (audio_codec)
     350            {
     351                if (!encoder)
     352                {
     353                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     354                    encoder = new AudioOutputDigitalEncoder();
     355                    if (!encoder->Init(audio_codec->codec_id,
     356                                audio_codec->bit_rate,
     357                                audio_codec->sample_rate,
     358                                audio_codec->channels
     359                                ))
     360                    {
     361                        // eeks
     362                        delete encoder;
     363                        encoder = NULL;
     364                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     365                    }
     366                }
     367            }
     368            if (encoder)
     369            {
     370                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     371                pSoundStretch->setChannels(audio_codec->channels);
     372            }
     373            else
     374            {
     375                pSoundStretch->setSampleRate(audio_samplerate);
     376                pSoundStretch->setChannels(audio_channels);
     377            }
     378        }
     379    }
    234380
    235381    // Setup visualisations, zero the visualisations buffers
    236382    prepareVisuals();
     
    290436        pSoundStretch = NULL;
    291437    }
    292438
     439    if (encoder)
     440    {
     441        delete encoder;
     442        encoder = NULL;
     443    }
     444
     445    if (upmixer)
     446    {
     447        delete upmixer;
     448        upmixer = NULL;
     449    }
     450    needs_upmix = false;
     451
    293452    CloseDevice();
    294453
    295454    killAudioLock.unlock();
     
    303462
    304463void AudioOutputBase::Pause(bool paused)
    305464{
     465    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    306466    pauseaudio = paused;
    307467    audio_actually_paused = false;
    308468}
     
    385545       The reason is that computing 'audiotime' requires acquiring the audio
    386546       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387547       from the audio thread, and then call this from the video thread. */
    388     int ret;
     548    long long ret;
    389549    struct timeval now;
    390550
    391551    if (audiotime == 0)
     
    397557
    398558    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399559    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     560    ret = (long long)(ret * audio_stretchfactor);
    401561
     562#if 1
     563    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     564            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     565            .arg(now.tv_sec).arg(now.tv_usec)
     566            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     567            .arg(ret)
     568            .arg(audiotime)
     569            .arg(audio_stretchfactor)
     570           );
     571#endif
     572
    402573    ret += audiotime;
    403574
    404575    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     576    return (int)ret;
    406577}
    407578
    408579void AudioOutputBase::SetAudiotime(void)
     
    439610    // include algorithmic latencies
    440611    if (pSoundStretch)
    441612    {
     613        // add the effect of any unused but processed samples, AC3 reencode does this
     614        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    442615        // add the effect of unprocessed samples in time stretch algo
    443616        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444617                              audio_bytes_per_sample) / audio_stretchfactor);
    445618    }
    446                
     619
     620    if (upmixer && needs_upmix)
     621    {
     622        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     623    }
     624
    447625    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448626                                   (audio_bytes_per_sample * effdspstretched));
    449627 
    450628    gettimeofday(&audiotime_updated, NULL);
     629#if 1
     630    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     631            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     632            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     633            .arg(audiotime)
     634            .arg(audbuf_timecode)
     635            .arg(totalbuffer)
     636            .arg(soundcard_buffer)
     637            .arg(effdspstretched)
     638            .arg(audio_bytes_per_sample)
     639            .arg(audio_stretchfactor)
     640           );
     641#endif
    451642
    452643    pthread_mutex_unlock(&avsync_lock);
    453644    pthread_mutex_unlock(&audio_buflock);
     
    458649{
    459650    // NOTE: This function is not threadsafe
    460651    int afree = audiofree(true);
    461     int abps = audio_bytes_per_sample;
     652    int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    462653    int len = samples * abps;
    463654
    464655    // Check we have enough space to write the data
    465656    if (need_resampler && src_ctx)
    466657        len = (int)ceilf(float(len) * src_data.src_ratio);
    467658
     659    // include samples in upmix buffer that may be flushed
     660    if (needs_upmix && upmixer)
     661        len += upmixer->numUnprocessedSamples()*abps;
     662
    468663    if (pSoundStretch)
    469664        len += (pSoundStretch->numUnprocessedSamples() +
    470665                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     
    520715    // NOTE: This function is not threadsafe
    521716
    522717    int afree = audiofree(true);
    523     int abps = audio_bytes_per_sample;
     718    int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    524719    int len = samples * abps;
    525720
    526721    // Check we have enough space to write the data
    527722    if (need_resampler && src_ctx)
    528723        len = (int)ceilf(float(len) * src_data.src_ratio);
    529724
     725    // include samples in upmix buffer that may be flushed
     726    if (needs_upmix && upmixer)
     727        len += upmixer->numUnprocessedSamples()*abps;
     728 
    530729    if (pSoundStretch)
    531730    {
    532731        len += (pSoundStretch->numUnprocessedSamples() +
     
    575774
    576775int AudioOutputBase::WaitForFreeSpace(int samples)
    577776{
    578     int len = samples * audio_bytes_per_sample;
     777    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     778    int len = samples * abps;
    579779    int afree = audiofree(false);
    580780
    581781    while (len > afree)
    582782    {
    583783        if (blocking)
    584784        {
    585             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     785            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    586786                    QString("(need %1, available %2)").arg(len).arg(afree));
    587787
    588788            // wait for more space
     
    591791        }
    592792        else
    593793        {
    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;
     794            VERBOSE(VB_IMPORTANT, LOC_ERR +
     795                    QString("Audio buffer overflow, %1 audio samples lost!")
     796                        .arg(samples - (afree / abps)));
     797            samples = afree / abps;
     798            len = samples * abps;
    598799            if (src_ctx)
    599800            {
    600801                int error = src_reset(src_ctx);
     
    619820   
    620821    int afree = audiofree(false);
    621822
    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));
     823    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     824    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     825            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6")
     826            .arg(samples)
     827            .arg(samples * abps)
     828            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     829            .arg(needs_upmix)
     830            );
    626831   
    627     len = WaitForFreeSpace(samples);
    628 
    629     if (interleaved)
     832    if (upmixer && needs_upmix)
    630833    {
    631         char *mybuf = (char*)buffer;
    632         int bdiff = AUDBUFSIZE - org_waud;
    633         if (bdiff < len)
     834        int out_samples = 0;
     835        int step = (interleaved)?source_audio_channels:1;
     836        len = WaitForFreeSpace(samples);    // test
     837        for(int itemp=0; itemp<samples; )
    634838        {
    635             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    636             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     839            // just in case it does a processing cycle, release the lock
     840            // to allow the output loop to do output
     841            pthread_mutex_unlock(&audio_buflock);
     842            if (audio_bytes == 2)
     843                itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     844            else
     845                itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     846            pthread_mutex_lock(&audio_buflock);
     847
     848            int copy_samples = upmixer->numSamples();
     849            if (copy_samples)
     850            {
     851                int copy_len = copy_samples * abps;
     852                out_samples += copy_samples;
     853                if (out_samples > samples)
     854                    len = WaitForFreeSpace(out_samples);
     855                int bdiff = AUDBUFSIZE - org_waud;
     856                if (bdiff < copy_len)
     857                {
     858                    int bdiff_samples = bdiff/abps;
     859                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples);
     860                    upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples));
     861                }
     862                else
     863                {
     864                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples);
     865                }
     866                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     867            }
    637868        }
    638         else
    639             memcpy(audiobuffer + org_waud, mybuf, len);
    640  
    641         org_waud = (org_waud + len) % AUDBUFSIZE;
    642     }
    643     else
     869        if (samples > 0)
     870        {
     871            len = WaitForFreeSpace(out_samples);
     872        }
     873        samples = out_samples;
     874    }
     875    else
    644876    {
    645         char **mybuf = (char**)buffer;
    646         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     877        len = WaitForFreeSpace(samples);
     878
     879        if (interleaved)
    647880        {
    648             for (int chan = 0; chan < audio_channels; chan++)
     881            char *mybuf = (char*)buffer;
     882            int bdiff = AUDBUFSIZE - org_waud;
     883            if (bdiff < len)
    649884            {
    650                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    651                 if (audio_bits == 16)
    652                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     885                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     886                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     887            }
     888            else
     889                memcpy(audiobuffer + org_waud, mybuf, len);
     890     
     891            org_waud = (org_waud + len) % AUDBUFSIZE;
     892        }
     893        else
     894        {
     895            char **mybuf = (char**)buffer;
     896            for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     897            {
     898                for (int chan = 0; chan < audio_channels; chan++)
     899                {
     900                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     901                    if (audio_bits == 16)
     902                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    653903
    654                 if (org_waud >= AUDBUFSIZE)
    655                     org_waud -= AUDBUFSIZE;
     904                    if (org_waud >= AUDBUFSIZE)
     905                        org_waud -= AUDBUFSIZE;
     906                }
    656907            }
    657908        }
    658909    }
    659910
    660     if (pSoundStretch)
     911    if (samples > 0)
    661912    {
    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)
     913        if (pSoundStretch)
    668914        {
    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         }
    679915
    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)
     916            // does not change the timecode, only the number of samples
     917            // back to orig pos
     918            org_waud = waud;
     919            int bdiff = AUDBUFSIZE - org_waud;
     920            int nSamplesToEnd = bdiff/abps;
     921            if (bdiff < len)
    688922            {
    689                 samplesToGet = nSamplesToEnd;   
     923                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     924                                          org_waud), nSamplesToEnd);
     925                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     926                                          (len - bdiff) / abps);
    690927            }
     928            else
     929            {
     930                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     931                                          org_waud), len / abps);
     932            }
    691933
    692             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    693                                       (audiobuffer + org_waud), samplesToGet);
    694             if (nSamples == nSamplesToEnd)
     934            if (encoder)
    695935            {
    696                 org_waud = 0;
    697                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     936                // pull out a packet's worth and reencode it until we dont have enough
     937                // for any more packets
     938                soundtouch::SAMPLETYPE* temp_buff =
     939                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     940                size_t frameSize = encoder->FrameSize()/abps;
     941                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     942                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     943                        .arg(frameSize)
     944                        .arg(encoder->FrameSize())
     945                        .arg(pSoundStretch->numSamples())
     946                       );
     947                // process the same number of samples as it creates a full encoded buffer
     948                // just like before
     949                while (pSoundStretch->numSamples() >= frameSize)
     950                {
     951                    int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     952                    int amount = encoder->Encode(temp_buff);
     953                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     954                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     955                            .arg(amount)
     956                            .arg(got)
     957                            .arg(pSoundStretch->numSamples())
     958                           );
     959                    if (amount == 0)
     960                        continue;
     961                    //len = WaitForFreeSpace(amount);
     962                    char * ob = encoder->GetOutBuff();
     963                    if (amount >= bdiff)
     964                    {
     965                        memcpy(audiobuffer + org_waud, ob, bdiff);
     966                        ob += bdiff;
     967                        amount -= bdiff;
     968                        org_waud = 0;
     969                    }
     970                    if (amount > 0)
     971                        memcpy(audiobuffer + org_waud, ob, amount);
     972                    bdiff = AUDBUFSIZE - amount;
     973                    org_waud += amount;
     974                }
    698975            }
    699976            else
    700977            {
    701                 org_waud += nSamples * audio_bytes_per_sample;
    702                 nSamplesToEnd -= nSamples;
     978                int newLen = 0;
     979                int nSamples;
     980                len = WaitForFreeSpace(pSoundStretch->numSamples() *
     981                                       audio_bytes_per_sample);
     982                do
     983                {
     984                    int samplesToGet = len/audio_bytes_per_sample;
     985                    if (samplesToGet > nSamplesToEnd)
     986                    {
     987                        samplesToGet = nSamplesToEnd;   
     988                    }
     989
     990                    nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     991                                              (audiobuffer + org_waud), samplesToGet);
     992                    if (nSamples == nSamplesToEnd)
     993                    {
     994                        org_waud = 0;
     995                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     996                    }
     997                    else
     998                    {
     999                        org_waud += nSamples * audio_bytes_per_sample;
     1000                        nSamplesToEnd -= nSamples;
     1001                    }
     1002
     1003                    newLen += nSamples * audio_bytes_per_sample;
     1004                    len -= nSamples * audio_bytes_per_sample;
     1005                } while (nSamples > 0);
    7031006            }
     1007        }
    7041008
    705             newLen += nSamples * audio_bytes_per_sample;
    706             len -= nSamples * audio_bytes_per_sample;
    707         } while (nSamples > 0);
    708     }
     1009        waud = org_waud;
     1010        lastaudiolen = audiolen(false);
    7091011
    710     waud = org_waud;
    711     lastaudiolen = audiolen(false);
     1012        if (timecode < 0)
     1013        {
     1014            // mythmusic doesn't give timestamps..
     1015            timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1016        }
     1017       
     1018        samples_buffered += samples;
     1019       
     1020        /* we want the time at the end -- but the file format stores
     1021           time at the start of the chunk. */
     1022        // even with timestretch, timecode is still calculated from original
     1023        // sample count
     1024        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7121025
    713     samples_buffered += samples;
    714    
    715     if (timecode < 0)
    716     {
    717         // mythmusic doesn't give timestamps..
    718         timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1026        if (interleaved)
     1027            dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits);
    7191028    }
    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);
    7261029
    727     if (interleaved)
    728         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    729 
    7301030    pthread_mutex_unlock(&audio_buflock);
    7311031}
    7321032
     
    7391039
    7401040    if (source_bitrate == -1)
    7411041    {
    742         source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1042        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
    7431043    }
    7441044
    7451045    if (ct / 1000 != current_seconds)
     
    7471047        current_seconds = ct / 1000;
    7481048        OutputEvent e(current_seconds, ct,
    7491049                      source_bitrate, audio_samplerate, audio_bits,
    750                       audio_channels);
     1050                      source_audio_channels);
    7511051        dispatch(e);
    7521052    }
    7531053}
     
    7801080            space_on_soundcard = getSpaceOnSoundcard();
    7811081
    7821082            if (space_on_soundcard != last_space_on_soundcard) {
    783                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1083                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7841084                        .arg(space_on_soundcard));
    7851085                last_space_on_soundcard = space_on_soundcard;
    7861086            }
     
    7931093                    WriteAudio(zeros, fragment_size);
    7941094                } else {
    7951095                    // this should never happen now -dag
    796                     VERBOSE(VB_AUDIO, LOC +
     1096                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    7971097                            QString("waiting for space on soundcard "
    7981098                                    "to write zeros: have %1 need %2")
    7991099                            .arg(space_on_soundcard).arg(fragment_size));
     
    8291129        if (fragment_size > audiolen(true))
    8301130        {
    8311131            if (audiolen(true) > 0)  // only log if we're sending some audio
    832                 VERBOSE(VB_AUDIO, LOC +
     1132                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8331133                        QString("audio waiting for buffer to fill: "
    8341134                                "have %1 want %2")
    8351135                        .arg(audiolen(true)).arg(fragment_size));
    8361136
    837             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1137            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8381138            pthread_mutex_lock(&audio_buflock);
    8391139            pthread_cond_broadcast(&audio_bufsig);
    8401140            pthread_mutex_unlock(&audio_buflock);
     
    8481148        if (fragment_size > space_on_soundcard)
    8491149        {
    8501150            if (space_on_soundcard != last_space_on_soundcard) {
    851                 VERBOSE(VB_AUDIO, LOC +
     1151                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8521152                        QString("audio waiting for space on soundcard: "
    8531153                                "have %1 need %2")
    8541154                        .arg(space_on_soundcard).arg(fragment_size));
     
    9101210
    9111211        /* update raud */
    9121212        raud = (raud + fragment_size) % AUDBUFSIZE;
    913         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1213        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9141214        pthread_cond_broadcast(&audio_bufsig);
    9151215
    9161216        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

     
    5252    QString real_device = (audio_passthru) ?
    5353        audio_passthru_device : audio_main_device;
    5454
     55    int index;
     56    if ((index=real_device.find('|'))>=0)
     57    {
     58        if (audio_channels >= 2)
     59            real_device = real_device.mid(index+1);
     60        else
     61            real_device = real_device.left(index);
     62    }
     63
    5564    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
    5665            .arg(real_device));
    5766
     
    8998    }
    9099    else
    91100    {
    92         fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
    93         buffer_time = 500000;  // .5 seconds
     101        //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
     102        //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits
     103        fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30);
     104        buffer_time = 100000;  // .5 seconds
    94105        period_time = buffer_time / 4;  // 4 interrupts per buffer
    95106    }
    96107
     
    162173   
    163174    tmpbuf = aubuf;
    164175
    165     VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
     176    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
    166177            .arg(size).arg(frames));
    167178   
    168179    while (frames > 0)
  • programs/mythfrontend/globalsettings.cpp

     
    5757#endif
    5858#ifdef USING_ALSA
    5959    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("Set the maximum number of audio channels to be decoded. "
     94                "This is for multi-channel/surround audio playback."));
     95    return gc;
     96}
     97
     98static HostComboBox *AudioUpmixType()
     99{
     100    HostComboBox *gc = new HostComboBox("AudioUpmixType",false);
     101    gc->setLabel(QObject::tr("Upmix"));
     102    gc->addSelection(QObject::tr("Passive"), "0");
     103    gc->addSelection(QObject::tr("Active Simple"), "1");
     104    gc->addSelection(QObject::tr("Active Linear"), "2", true); // default
     105    gc->setHelpText(
     106            QObject::tr("Set the audio upmix type for 2ch to 6ch conversion. "
     107                "This is for multi-channel/surround audio playback."));
     108    return gc;
     109}
     110
    81111static HostComboBox *PassThroughOutputDevice()
    82112{
    83113    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    31453175         vgrp0->addChild(AC3PassThrough());
    31463176         vgrp0->addChild(DTSPassThrough());
    31473177
     3178         HorizontalConfigurationGroup *agrp =
     3179             new HorizontalConfigurationGroup(false, false, true, true);
     3180         agrp->addChild(MaxAudioChannels());
     3181         agrp->addChild(AudioUpmixType());
     3182         addChild(agrp);
     3183
    31483184         VerticalConfigurationGroup *vgrp1 =
    31493185             new VerticalConfigurationGroup(false, false, true, true);
    31503186         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 * = NULL)
    5960    {
     61        ClearError();
    6062        (void)audio_samplerate;
    6163        (void)audio_passthru;
    6264        bits = audio_bits;
    6365        channels = audio_channels;
    6466        bytes_per_sample = bits * channels / 8;
     67        if (channels>2)
     68            Error("Invalid channel count");
    6569    }
    6670
    6771    // dsprate is in 100 * samples/second
  • programs/mythuitest/mythuitest.pro

     
    66TARGET = mythuitest
    77CONFIG += thread opengl
    88
     9LIBS += -L../../libs/libavcodec -L../../libs/libavutil
     10LIBS += -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION
    911LIBS += $$EXTRA_LIBS
    1012
     13TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
     14TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
     15
    1116macx {
    1217    # Duplication of source with libmyth (e.g. oldsettings.cpp)
    1318    # means that the linker complains, so we have to ignore duplicates
  • libs/libmythtv/avformatdecoder.h

     
    259259    bool              allow_ac3_passthru;
    260260    bool              allow_dts_passthru;
    261261    bool              disable_passthru;
     262    int               max_channels;
    262263
    263264    AudioInfo         audioIn;
    264265    AudioInfo         audioOut;
  • 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);
     
    417414
    418415    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    419416    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     417    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    420418
    421419    audioIn.sample_size = -32; // force SetupAudioStream to run once
    422420    itv = GetNVP()->GetInteractiveTV();
     
    15801578                            <<") already open, leaving it alone.");
    15811579                }
    15821580                //assert(enc->codec_id);
     1581                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
    15831582
     1583#if 0
     1584                // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this
    15841585                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15851586                if (enc->codec_id == CODEC_ID_DTS)
    15861587                {
     
    15891590                    // enc->bit_rate = what??;
    15901591                }
    15911592                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1593#endif
    15921594
    15931595                bitrate += enc->bit_rate;
    15941596                break;
     
    32603262                    if (!curstream->codec->channels)
    32613263                    {
    32623264                        QMutexLocker locker(&avcodeclock);
    3263                         curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3265                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     3266                        curstream->codec->channels = audioOut.channels;
    32643267                        ret = avcodec_decode_audio(
    32653268                            curstream->codec, audioSamples,
    32663269                            &data_size, ptr, len);
     
    33213324                        AVCodecContext *ctx = curstream->codec;
    33223325
    33233326                        if ((ctx->channels == 0) ||
    3324                             (ctx->channels > MAX_OUTPUT_CHANNELS))
    3325                             ctx->channels = MAX_OUTPUT_CHANNELS;
     3327                            (ctx->channels > audioOut.channels))
     3328                            ctx->channels = audioOut.channels;
    33263329
    33273330                        ret = avcodec_decode_audio(
    33283331                            ctx, audioSamples, &data_size, ptr, len);
     
    36733676
    36743677void AvFormatDecoder::SetDisablePassThrough(bool disable)
    36753678{
     3679    // can only disable never reenable as once timestretch is on its on for the session
     3680    if (disable_passthru)
     3681        return;
    36763682    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    36773683    {
    36783684        disable_passthru = disable;
     
    37053711    AVCodecContext *codec_ctx = NULL;
    37063712    AudioInfo old_in  = audioIn;
    37073713    AudioInfo old_out = audioOut;
     3714    bool using_passthru = false;
    37083715
    37093716    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    37103717        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    37163723        assert(curstream->codec);
    37173724        codec_ctx = curstream->codec;       
    37183725        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3719                                 !disable_passthru &&
    37203726                                (codec_ctx->codec_id == CODEC_ID_AC3));
    37213727        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3722                                 !disable_passthru &&
    37233728                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3729        using_passthru = do_ac3_passthru || do_dts_passthru;
    37243730        info = AudioInfo(codec_ctx->codec_id,
    37253731                         codec_ctx->sample_rate, codec_ctx->channels,
    3726                          do_ac3_passthru || do_dts_passthru);
     3732                         using_passthru && !disable_passthru);
    37273733    }
    37283734
    37293735    if (info == audioIn)
    37303736        return false; // no change
    37313737
     3738    QString ptmsg = "";
     3739    if (using_passthru)
     3740    {
     3741        ptmsg = QString(" using passthru");
     3742    }
    37323743    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    37333744            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    37343745
    37353746    audioOut = audioIn = info;
    3736     if (audioIn.do_passthru)
     3747    if (using_passthru)
    37373748    {
    37383749        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3739         audioOut.channels    = 2;
    3740         audioOut.sample_rate = 48000;
    3741         audioOut.sample_size = 4;
     3750        AudioInfo digInfo = audioOut;
     3751        if (!disable_passthru)
     3752        {
     3753            digInfo.channels    = 2;
     3754            digInfo.sample_rate = 48000;
     3755            digInfo.sample_size = 4;
     3756        }
     3757        if (audioOut.channels > max_channels)
     3758        {
     3759            audioOut.channels = max_channels;
     3760            audioOut.sample_size = audioOut.channels * 2;
     3761            codec_ctx->channels = audioOut.channels;
     3762        }
     3763        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3764                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3765                .arg(digInfo.toString())
     3766                .arg(old_in.toString()).arg(old_out.toString())
     3767                .arg(audioIn.toString()).arg(audioOut.toString()));
     3768
     3769        if (digInfo.sample_rate > 0)
     3770            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3771
     3772        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3773                                 digInfo.sample_rate, audioIn.do_passthru);
     3774        // allow the audio stuff to reencode
     3775        GetNVP()->SetAudioCodec(codec_ctx);
     3776        GetNVP()->ReinitAudio();
     3777        return true;
    37423778    }
    37433779    else
    37443780    {
    3745         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3781        if (audioOut.channels > max_channels)
    37463782        {
    3747             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3783            audioOut.channels = max_channels;
    37483784            audioOut.sample_size = audioOut.channels * 2;
    3749             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3785            codec_ctx->channels = audioOut.channels;
    37503786        }
    37513787    }
     3788    bool audiook;
    37523789
    37533790    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    37543791            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    37613798    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    37623799                             audioOut.sample_rate,
    37633800                             audioIn.do_passthru);
    3764     GetNVP()->ReinitAudio();
     3801    // allow the audio stuff to reencode
     3802    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3803    QString errMsg = GetNVP()->ReinitAudio();
     3804    audiook = errMsg.isEmpty();
    37653805
    37663806    return true;
    37673807}
  • 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; }
     
    682683    int      audio_bits;
    683684    int      audio_samplerate;
    684685    float    audio_stretchfactor;
     686    void     *audio_codec;
    685687    bool     audio_passthru;
    686688
    687689    // Picture-in-Picture
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    206206      audio_passthru_device(QString::null),
    207207      audio_channels(2),            audio_bits(-1),
    208208      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     209      audio_codec(NULL),
    209210      // Picture-in-Picture
    210211      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    211212      // Preview window support
     
    767768    if (audioOutput)
    768769    {
    769770        audioOutput->Reconfigure(audio_bits, audio_channels,
    770                                  audio_samplerate, audio_passthru);
     771                                 audio_samplerate, audio_passthru,
     772                                 audio_codec);
    771773        errMsg = audioOutput->GetError();
    772774        if (!errMsg.isEmpty())
    773775            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    36503657    audio_passthru = passthru;
    36513658}
    36523659
     3660void NuppelVideoPlayer::SetAudioCodec(void* ac)
     3661{
     3662    audio_codec = ac;
     3663}
     3664
    36533665void NuppelVideoPlayer::SetEffDsp(int dsprate)
    36543666{
    36553667    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
     
    177352                    /* update codec info */
    178353                    avctx->sample_rate = sample_rate;
    179354                    s->channels = ac3_channels[s->flags & 7];
     355                    if (avctx->cqp >= 0)
     356                        avctx->channels = avctx->cqp;
    180357                    if (s->flags & A52_LFE)
    181358                        s->channels++;
    182359                    if (avctx->channels == 0)
     
    199376            s->inbuf_ptr += len;
    200377            buf_size -= len;
    201378        } else {
     379            int chans;
    202380            flags = s->flags;
    203381            if (avctx->channels == 1)
    204382                flags = A52_MONO;
    205             else if (avctx->channels == 2)
    206                 flags = A52_STEREO;
     383            else if (avctx->channels == 2) {
     384                if (s->channels>2)
     385                    flags = A52_DOLBY;
     386                else
     387                    flags = A52_STEREO;
     388            }
    207389            else
    208390                flags |= A52_ADJUST_LEVEL;
    209391            level = 1;
     392            chans = channels_multi(flags);
    210393            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    211394            fail:
    212395                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    217400            for (i = 0; i < 6; i++) {
    218401                if (s->a52_block(s->state))
    219402                    goto fail;
    220                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     403                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    221404            }
    222405            s->inbuf_ptr = s->inbuf;
    223406            s->frame_size = 0;
  • libs/libavcodec/ac3_parser.c

     
    8484    return 0;
    8585}
    8686
    87 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
     87/*static*/ int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
    8888                    int *bit_rate, int *samples)
    8989{
    9090    int err;