Ticket #1104: mythtv_ac3.40.patch

File mythtv_ac3.40.patch, 126.5 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;
     33const float center_level = 0.5*sqrt(0.5);   // gain of the center channel
     34
     35// private implementation of the surround decoder
     36class decoder_impl {
     37public:
     38    // create an instance of the decoder
     39    //  blocksize is fixed over the lifetime of this object for performance reasons
     40    decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
     41        // create FFTW buffers
     42        lt = (float*)fftwf_malloc(sizeof(float)*N);
     43        rt = (float*)fftwf_malloc(sizeof(float)*N);
     44        dst = (float*)fftwf_malloc(sizeof(float)*N);
     45        dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     46        dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     47        src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     48        loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE);
     49        loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE);
     50        store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE);   
     51        // resize our own buffers
     52        frontR.resize(N);
     53        frontL.resize(N);
     54        avg.resize(N);
     55        surR.resize(N);
     56        surL.resize(N);
     57#ifdef FILTERED_LFE
     58        trueavg.resize(N);
     59#endif
     60        xfs.resize(N);
     61        yfs.resize(N);
     62        inbuf[0].resize(N);
     63        inbuf[1].resize(N);
     64        for (unsigned c=0;c<6;c++) {
     65            outbuf[c].resize(N);
     66            filter[c].resize(N);
     67        }
     68        sample_rate(48000);
     69        // generate the window function (square root of hann, b/c it is applied before and after the transform)
     70        wnd.resize(N);
     71        // dft normalization included in the window for zero cost scaling
     72        // also add a gain factor of *2 due to processing gain in algo (see center_level)
     73        for (unsigned k=0;k<N;k++)
     74            wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
     75        current_buf = 0;
     76        // set the default coefficients
     77        surround_coefficients(0.8165,0.5774);
     78        phase_mode(0);
     79        separation(1,1);
     80        steering_mode(1);
     81    }
     82
     83    // destructor
     84    ~decoder_impl() {
     85        // clean up the FFTW stuff
     86        fftwf_destroy_plan(store);
     87        fftwf_destroy_plan(loadR);
     88        fftwf_destroy_plan(loadL);
     89        fftwf_free(src);
     90        fftwf_free(dftR);
     91        fftwf_free(dftL);
     92        fftwf_free(dst);
     93        fftwf_free(rt);
     94        fftwf_free(lt);
     95    }
     96
     97    float ** getInputBuffers()
     98    {
     99        inbufs[0] = &inbuf[0][current_buf*halfN];
     100        inbufs[1] = &inbuf[1][current_buf*halfN];
     101        return inbufs;
     102    }
     103
     104    float ** getOutputBuffers()
     105    {
     106        outbufs[0] = &outbuf[0][current_buf*halfN];
     107        outbufs[1] = &outbuf[1][current_buf*halfN];
     108        outbufs[2] = &outbuf[2][current_buf*halfN];
     109        outbufs[3] = &outbuf[3][current_buf*halfN];
     110        outbufs[4] = &outbuf[4][current_buf*halfN];
     111        outbufs[5] = &outbuf[5][current_buf*halfN];
     112        return outbufs;
     113    }
     114
     115    // decode a chunk of stereo sound, has to contain exactly blocksize samples
     116    //  center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution
     117    //  dimension [0..1] moves the soundfield backwards, 0=front, 1=side
     118    //  adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption
     119    void decode(float center_width, float dimension, float adaption_rate) {
     120        // process first part
     121        int index;
     122        index = current_buf*halfN;
     123        float *in_second[2] = {&inbuf[0][index],&inbuf[1][index]};
     124        current_buf ^= 1;
     125        index = current_buf*halfN;
     126        float *in_first[2] = {&inbuf[0][index],&inbuf[1][index]};
     127        add_output(in_first,in_second,center_width,dimension,adaption_rate,true);
     128        // shift last half of input buffer to the beginning
     129    }
     130   
     131    // flush the internal buffers
     132    void flush() {
     133        for (unsigned k=0;k<N;k++) {
     134            for (unsigned c=0;c<6;c++)
     135                outbuf[c][k] = 0;
     136            inbuf[0][k] = 0;
     137            inbuf[1][k] = 0;
     138        }
     139    }
     140
     141    // set lfe filter params
     142    void sample_rate(unsigned int srate) {
     143        // lfe filter is just straight through band limited
     144        unsigned int cutoff = (250*N)/srate;
     145        for (unsigned f=0;f<=halfN;f++) {           
     146            if ((f>=2) && (f<cutoff))
     147                filter[5][f] = 1.0;
     148            else
     149                filter[5][f] = 0.0;
     150        }
     151    }
     152
     153    // set the assumed surround mixing coefficients
     154    void surround_coefficients(float a, float b) {
     155        master_gain = 1.0;
     156        // calc the simple coefficients
     157        surround_high = a;
     158        surround_low = b;
     159        surround_balance = (a-b)/(a+b);
     160        surround_level = 1/(a+b);
     161        // calc the linear coefficients
     162        cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0);
     163        A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n;
     164        E = (o+v)*n; F = (o+u)*n; G = (o-v)*n;  H = (o-u)*n;
     165    }
     166
     167    // set the phase shifting mode
     168    void phase_mode(unsigned mode) {
     169        const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}};
     170        phase_offsetL = modes[mode][0];
     171        phase_offsetR = modes[mode][1];
     172    }
     173
     174    // what steering mode should be chosen
     175    void steering_mode(bool mode) { linear_steering = mode; }
     176
     177    // set front & rear separation controls
     178    void separation(float front, float rear) {
     179        front_separation = front;
     180        rear_separation = rear;
     181    }
     182
     183private:
     184    // polar <-> cartesian coodinates conversion
     185    static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); }
     186    static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); }
     187    static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); }
     188    static inline float sqr(float x) { return x*x; }
     189    // the dreaded min/max
     190    static inline float min(float a, float b) { return a<b?a:b; }
     191    static inline float max(float a, float b) { return a>b?a:b; }
     192    static inline float clamp(float x) { return max(-1,min(1,x)); }
     193
     194    // handle the output buffering for overlapped calls of block_decode
     195    void add_output(float *input1[2], float *input2[2], float center_width, float dimension, float adaption_rate, bool result=false) {
     196        // add the windowed data to the last 1/2 of the output buffer
     197        float *out[6] = {&outbuf[0][0],&outbuf[1][0],&outbuf[2][0],&outbuf[3][0],&outbuf[4][0],&outbuf[5][0]};
     198        block_decode(input1,input2,out,center_width,dimension,adaption_rate);
     199    }
     200
     201    // CORE FUNCTION: decode a block of data
     202    void block_decode(float *input1[2], float *input2[2], float *output[6], float center_width, float dimension, float adaption_rate) {
     203        // 1. scale the input by the window function; this serves a dual purpose:
     204        // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed
     205        // - second it allows for smooth blending of varying filters between the blocks
     206        {
     207            float* pWnd = &wnd[0];
     208            float* pLt = &lt[0];
     209            float* pRt = &rt[0];
     210            float* pIn0 = input1[0];
     211            float* pIn1 = input1[1];
     212            for (unsigned k=0;k<halfN;k++) {
     213                *pLt++ = *pIn0++ * *pWnd;
     214                *pRt++ = *pIn1++ * *pWnd++;
     215            }
     216            pIn0 = input2[0];
     217            pIn1 = input2[1];
     218            //for (unsigned k=0,k1=halfN;k<halfN;k++,k1++) {
     219            for (unsigned k=0;k<halfN;k++) {
     220                *pLt++ = *pIn0++ * *pWnd;
     221                *pRt++ = *pIn1++ * *pWnd++;
     222            }
     223        }
     224
     225        // ... and tranform it into the frequency domain
     226        fftwf_execute(loadL);
     227        fftwf_execute(loadR);
     228
     229        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
     230        for (unsigned f=0;f<=halfN;f++) {           
     231            // get left/right amplitudes/phases
     232            float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
     233            float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
     234//          if (ampL+ampR < epsilon)
     235//              continue;       
     236
     237            // calculate the amplitude/phase difference
     238            float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
     239            float phaseDiff = phaseL - phaseR;
     240            if (phaseDiff < -PI) phaseDiff += 2*PI;
     241            if (phaseDiff > PI) phaseDiff -= 2*PI;
     242            phaseDiff = abs(phaseDiff);
     243
     244            if (linear_steering) {
     245/*              cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);
     246                cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w;              */
     247//              xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();
     248//              yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);
     249
     250                /*
     251                Problem:
     252                This assumes that the values are interpolated linearly between the cardinal points.
     253                But this way we have no chance of knowing the average volume...
     254                - Can we solve that computing everything under the assumption of normalized volume?
     255                  No. Seemingly not.
     256                - Maybe we should add w explitcitly into the equation and see if we can solve it...
     257                */
     258
     259
     260                //cfloat lt(0.5,0),rt(0.5,0);
     261                //cfloat x(0,0), y(1,0);
     262                /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);
     263                cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);
     264                cfloat s = sqrt(p*p/4.0f - q);
     265                cfloat x = -p;
     266                cfloat x1 = -p/2.0f + s;
     267                cfloat x2 = -p/2.0f - s;
     268                float x = 0;
     269                if (x1.real() >= -1 && x1.real() <= 1)
     270                    x = x1.real();
     271                else if (x2.real() >= -1 && x2.real() <= 1)
     272                    x = x2.real();*/
     273
     274                //cfloat yp = (rt - (x*E+H))/(F+x*G);
     275                //cfloat xp = (lt - (y*B+D))/(A+y*C);
     276
     277                /*xfs[f] = x;
     278                yfs[f] = y.real();*/
     279
     280                // --- this is the fancy new linear mode ---
     281
     282                // get sound field x/y position
     283                yfs[f] = get_yfs(ampDiff,phaseDiff);
     284                xfs[f] = get_xfs(ampDiff,yfs[f]);
     285
     286                // add dimension control
     287                yfs[f] = clamp(yfs[f] - dimension);
     288
     289                // add crossfeed control
     290                xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
     291
     292                // 3. generate frequency filters for each output channel
     293                float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
     294                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
     295                float volume[5] = {
     296                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),  // left
     297                    front * center_level*((1-abs(xfs[f])) * (1-center_width)),          // center
     298                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right
     299                    back * surround_level * left,                                       // left surround
     300                    back * surround_level * right                                       // right surround
     301                };
     302
     303                // adapt the prior filter
     304                for (unsigned c=0;c<5;c++)
     305                    filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/*/N*/;
     306
     307            } else {
     308                // --- this is the old & simple steering mode ---
     309
     310                // calculate the amplitude/phase difference
     311                float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
     312                float phaseDiff = phaseL - phaseR;
     313                if (phaseDiff < -PI) phaseDiff += 2*PI;
     314                if (phaseDiff > PI) phaseDiff -= 2*PI;
     315                phaseDiff = abs(phaseDiff);
     316
     317                // determine sound field x-position
     318                xfs[f] = ampDiff;
     319
     320                // determine preliminary sound field y-position from phase difference
     321                yfs[f] = 1 - (phaseDiff/PI)*2;
     322
     323                if (abs(xfs[f]) > surround_balance) {
     324                    // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance
     325                    // this is necessary because the sound field is trapezoidal and will be stretched behind the listener
     326                    float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance);
     327                    yfs[f]  = (1-frontness) * yfs[f] + frontness * 1;
     328                }
     329
     330                // add dimension control
     331                yfs[f] = clamp(yfs[f] - dimension);
     332
     333                // add crossfeed control
     334                xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
     335
     336                // 3. generate frequency filters for each output channel, according to the signal position
     337                // the sum of all channel volumes must be 1.0
     338                float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
     339                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
     340                float volume[5] = {
     341                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),      // left
     342                    front * center_level*((1-abs(xfs[f])) * (1-center_width)),              // center
     343                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)),     // right
     344                    back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))),  // left surround
     345                    back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2)))   // right surround
     346                };
     347
     348                // adapt the prior filter
     349                for (unsigned c=0;c<5;c++)
     350                    filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/*/N*/;
     351            }
     352
     353            // ... and build the signal which we want to position
     354            frontL[f] = polar(ampL+ampR,phaseL);
     355            frontR[f] = polar(ampL+ampR,phaseR);
     356            avg[f] = frontL[f] + frontR[f];
     357            surL[f] = polar(ampL+ampR,phaseL+phase_offsetL);
     358            surR[f] = polar(ampL+ampR,phaseR+phase_offsetR);
     359#ifdef FILTERED_LFE
     360            trueavg[f] = cfloat(dftL[f][0] + dftR[f][0], dftL[f][1] + dftR[f][1]);
     361#endif
     362        }
     363
     364        // 4. distribute the unfiltered reference signals over the channels
     365        apply_filter(&frontL[0],&filter[0][0],&output[0][0]);   // front left
     366        apply_filter(&avg[0], &filter[1][0],&output[1][0]);     // front center
     367        apply_filter(&frontR[0],&filter[2][0],&output[2][0]);   // front right
     368        apply_filter(&surL[0],&filter[3][0],&output[3][0]);     // surround left
     369        apply_filter(&surR[0],&filter[4][0],&output[4][0]);     // surround right
     370#ifdef FILTERED_LFE
     371        apply_filter(&trueavg[0],&filter[5][0],&output[5][0]);  // lfe
     372#else
     373        float* out5 = &output[5][(current_buf)*halfN];
     374        float* in2l = &input2[0][0];
     375        float* in2r = &input2[1][0];
     376        //for (unsigned k=0,k2=N/4;k<halfN;k++,k2++) {
     377        for (unsigned k=0;k<halfN;k++) {
     378            *out5++ = *in2l++ + *in2r++;
     379        }
     380#endif
     381    }
     382
     383#define FASTER_CALC
     384    // map from amplitude difference and phase difference to yfs
     385    inline double get_yfs(double ampDiff, double phaseDiff) {
     386        double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2);
     387#ifdef FASTER_CALC
     388        double tanX = tan(x);
     389        return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
     390            + 0.09170680403453149*x*x*x + 0.2617754892323973*tanX - 0.04180413533856156*sqr(tanX);
     391#else
     392        return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
     393            + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x));
     394#endif
     395    }
     396
     397    // map from amplitude difference and yfs to xfs
     398    inline double get_xfs(double ampDiff, double yfs) {
     399        double x=ampDiff,y=yfs;
     400#ifdef FASTER_CALC
     401        double tanX = tan(x);
     402        double tanY = tan(y);
     403        double asinX = asin(x);
     404        double sinX = sin(x);
     405        double sinY = sin(y);
     406        double x3 = x*x*x;
     407        double y2 = y*y;
     408        double y3 = y*y2;
     409        return 2.464833559224702*x - 423.52131153259404*x*y +
     410            67.8557858606918*x3*y + 788.2429425544392*x*y2 -
     411            79.97650354902909*x3*y2 - 513.8966153850349*x*y3 +
     412            35.68117670186306*x3*y3 + 13867.406173420834*y*asinX -
     413            2075.8237075786396*y2*asinX - 908.2722068360281*y3*asinX -
     414            12934.654772878019*asinX*sinY - 13216.736529661162*y*tanX +
     415            1288.6463247741938*y2*tanX + 1384.372969378453*y3*tanX +
     416            12699.231471126128*sinY*tanX + 95.37131275594336*sinX*tanY -
     417            91.21223198407546*tanX*tanY;
     418#else
     419        return 2.464833559224702*x - 423.52131153259404*x*y +
     420            67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y -
     421            79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y +
     422            35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) -
     423            2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) -
     424            12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) +
     425            1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) +
     426            12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) -
     427            91.21223198407546*tan(x)*tan(y);
     428#endif
     429    }
     430
     431    // filter the complex source signal and add it to target
     432    void apply_filter(cfloat *signal, float *flt, float *target) {
     433        // filter the signal
     434        for (unsigned f=0;f<=halfN;f++) {       
     435            src[f][0] = signal[f].real() * flt[f];
     436            src[f][1] = signal[f].imag() * flt[f];
     437        }
     438        // transform into time domain
     439        fftwf_execute(store);
     440
     441        float* pT1   = &target[current_buf*halfN];
     442        float* pWnd1 = &wnd[0];
     443        float* pDst1 = &dst[0];
     444        float* pT2   = &target[(current_buf^1)*halfN];
     445        float* pWnd2 = &wnd[halfN];
     446        float* pDst2 = &dst[halfN];
     447        // add the result to target, windowed
     448        for (unsigned int k=0;k<halfN;k++)
     449        {
     450            // 1st part is overlap add
     451            *pT1++ += *pWnd1++ * *pDst1++;
     452            // 2nd part is set as has no history
     453            *pT2++ = *pWnd2++ * *pDst2++;
     454        }
     455    }
     456
     457    unsigned int N;                    // the block size
     458    unsigned int halfN;                // half block size precalculated
     459    // FFTW data structures
     460    float *lt,*rt,*dst;                // left total, right total (source arrays), destination array
     461    fftwf_complex *dftL,*dftR,*src;    // intermediate arrays (FFTs of lt & rt, processing source)
     462    fftwf_plan loadL,loadR,store;      // plans for loading the data into the intermediate format and back
     463    // buffers
     464    std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain
     465#ifdef FILTERED_LFE
     466    std::vector<cfloat> trueavg;       // for lfe generation
     467#endif
     468    std::vector<float> xfs,yfs;        // the feature space positions for each frequency bin
     469    std::vector<float> wnd;            // the window function, precalculated
     470    std::vector<float> filter[6];      // a frequency filter for each output channel
     471    std::vector<float> inbuf[2];       // the sliding input buffers
     472    std::vector<float> outbuf[6];      // the sliding output buffers
     473    // coefficients
     474    float surround_high,surround_low;  // high and low surround mixing coefficient (e.g. 0.8165/0.5774)
     475    float surround_balance;            // the xfs balance that follows from the coeffs
     476    float surround_level;              // gain for the surround channels (follows from the coeffs
     477    float master_gain;                 // gain for all channels
     478    float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels
     479    float front_separation;            // front stereo separation
     480    float rear_separation;             // rear stereo separation
     481    bool linear_steering;              // whether the steering should be linear or not
     482    cfloat A,B,C,D,E,F,G,H;            // coefficients for the linear steering
     483    int current_buf;                   // specifies which buffer is 2nd half of input sliding buffer
     484    float * inbufs[2];                 // for passing back to driver
     485    float * outbufs[6];                // for passing back to driver
     486
     487    friend class fsurround_decoder;
     488};
     489
     490
     491// implementation of the shell class
     492
     493fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { }
     494
     495fsurround_decoder::~fsurround_decoder() { delete impl; }
     496
     497void fsurround_decoder::decode(float center_width, float dimension, float adaption_rate) {
     498    impl->decode(center_width,dimension,adaption_rate);
     499}
     500
     501void fsurround_decoder::flush() { impl->flush(); }
     502
     503void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); }
     504
     505void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); }
     506
     507void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); }
     508
     509void fsurround_decoder::separation(float front, float rear) { impl->separation(front,rear); }
     510
     511float ** fsurround_decoder::getInputBuffers()
     512{
     513    return impl->getInputBuffers();
     514}
     515
     516float ** fsurround_decoder::getOutputBuffers()
     517{
     518    return impl->getOutputBuffers();
     519}
     520
     521void fsurround_decoder::sample_rate(unsigned int samplerate)
     522{
     523    impl->sample_rate(samplerate);
     524}
  • 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
     226FreeSurround::fsurround_params::fsurround_params(
     227        int32_t center_width,
     228        int32_t dimension
     229    ) :
     230    center_width(center_width),
     231    dimension(dimension),
     232    coeff_a(0.8165),coeff_b(0.5774),
     233    phasemode(0),
     234    steering(1),
     235    front_sep(100),
     236    rear_sep(100)
     237{
     238}
     239
     240FreeSurround::~FreeSurround()
     241{
     242    VERBOSE(QString("FreeSurround::~FreeSurround"));
     243    close();
     244    /*
     245    if (bufs)
     246    {
     247        bp.release((void*)1);
     248        bufs = NULL;
     249    }
     250    */
     251    if (int16bufs)
     252    {
     253        bp16.release((void*)1);
     254        int16bufs = NULL;
     255    }
     256    VERBOSE(QString("FreeSurround::~FreeSurround done"));
     257}
     258
     259uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step)
     260{
     261    int i;
     262    int ic = in_count;
     263    int bs = block_size/2;
     264    bool process = true;
     265    // demultiplex
     266    switch (surround_mode)
     267    {
     268        case SurroundModePassive:
     269            switch (numChannels)
     270            {
     271                case 1:
     272                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     273                    {
     274                        int16bufs->l[ic] =
     275                        int16bufs->c[ic] =
     276                        int16bufs->r[ic] =
     277                            samples[i] >> 1;
     278                    }
     279                    break;
     280                case 2:
     281                    if (step>0)
     282                    {
     283                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     284                        {
     285                            short lt = samples[i] >> 1;
     286                            short rt = samples[i+step] >> 1;
     287                            int16bufs->l[ic] = lt;
     288                            int16bufs->lfe[ic] =
     289                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     290                            int16bufs->r[ic] = rt;
     291                            int16bufs->ls[ic] =
     292                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     293                        }
     294                    }
     295                    else
     296                    {
     297                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     298                        {
     299                            short lt = samples[i*2] >> 1;
     300                            short rt = samples[i*2+1] >> 1;
     301                            int16bufs->l[ic] = lt;
     302                            int16bufs->lfe[ic] =
     303                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     304                            int16bufs->r[ic] = rt;
     305                            int16bufs->ls[ic] =
     306                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     307                        }
     308                    }
     309                    break;
     310                case 6:
     311                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     312                    {
     313                        int16bufs->l[ic] = *samples++ >> 1;
     314                        int16bufs->c[ic] = *samples++ >> 1;
     315                        int16bufs->r[ic] = *samples++ >> 1;
     316                        int16bufs->ls[ic] = *samples++ >> 1;
     317                        int16bufs->rs[ic] = *samples++ >> 1;
     318                        int16bufs->lfe[ic] = *samples++ >> 1;
     319                    }
     320                    break;
     321            }
     322            in_count = 0;
     323            out_count = ic;
     324            processed_size = ic;
     325            processed = false;
     326            break;
     327
     328        default:
     329            {
     330                float** inputs = decoder->getInputBuffers();
     331                float * lt = &inputs[0][ic];
     332                float * rt = &inputs[1][ic];
     333                if ((ic+numSamples) > bs)
     334                    numSamples = bs - ic;
     335                switch (numChannels)
     336                {
     337                    case 1:
     338                        for (i=0;i<numSamples;i++)
     339                        {
     340                            *lt++ =
     341                            *rt++ =
     342                                *samples++ MASTER_GAIN;
     343                        }
     344                        break;
     345                    case 2:
     346                        if (step>0)
     347                        {
     348                            for (i=0;i<numSamples;i++)
     349                            {
     350                                *lt++ = samples[0] MASTER_GAIN;
     351                                *rt++ = samples[step] MASTER_GAIN;
     352                                samples++;
     353                            }
     354                        }
     355                        else
     356                        {
     357                            for (i=0;i<numSamples;i++)
     358                            {
     359                                *lt++ = *samples++ MASTER_GAIN;
     360                                *rt++ = *samples++ MASTER_GAIN;
     361                            }
     362                        }
     363                        break;
     364                    case 6:
     365                        {
     366                        process = false;
     367                        short * l = &int16bufs->l[ic];
     368                        short * c = &int16bufs->c[ic];
     369                        short * r = &int16bufs->r[ic];
     370                        short * ls = &int16bufs->ls[ic];
     371                        short * rs = &int16bufs->rs[ic];
     372                        short * lfe = &int16bufs->lfe[ic];
     373                        for (i=0;i<numSamples;i++)
     374                        {
     375                            *l++ = *samples++ >> 1;
     376                            *c++ = *samples++ >> 1;
     377                            *r++ = *samples++ >> 1;
     378                            *ls++ = *samples++ >> 1;
     379                            *rs++ = *samples++ >> 1;
     380                            *lfe++ = *samples++ >> 1;
     381                        }
     382                        } break;
     383                }
     384                ic += numSamples;
     385                in_count = ic;
     386                processed = process;
     387                if (ic == bs)
     388                {
     389                    in_count = 0;
     390                    if (process)
     391                        process_block();
     392                    out_count = bs;
     393                    processed_size = bs;
     394                }
     395            } break;
     396    }
     397    VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5")
     398            .arg(numSamples)
     399            .arg(numChannels)
     400            .arg(step)
     401            .arg(i)
     402            .arg(out_count)
     403           );
     404    return i;
     405}
     406
     407uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step)
     408{
     409    int i;
     410    int ic = in_count;
     411    int bs = block_size/2;
     412    bool process = true;
     413    // demultiplex
     414    switch (surround_mode)
     415    {
     416        case SurroundModePassive:
     417            switch (numChannels)
     418            {
     419                case 1:
     420                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     421                    {
     422                        int16bufs->l[ic] =
     423                        int16bufs->c[ic] =
     424                        int16bufs->r[ic] =
     425                            samples[i] << 7;
     426                    }
     427                    break;
     428                case 2:
     429                    if (step>0)
     430                    {
     431                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     432                        {
     433                            short lt = samples[i] << 7;
     434                            short rt = samples[i+step] << 7;
     435                            int16bufs->l[ic] = lt;
     436                            int16bufs->lfe[ic] =
     437                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     438                            int16bufs->r[ic] = rt;
     439                            int16bufs->ls[ic] =
     440                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     441                        }
     442                    }
     443                    else
     444                    {
     445                        for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     446                        {
     447                            short lt = samples[i*2] << 7;
     448                            short rt = samples[i*2+1] << 7;
     449                            int16bufs->l[ic] = lt;
     450                            int16bufs->lfe[ic] =
     451                            int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5)
     452                            int16bufs->r[ic] = rt;
     453                            int16bufs->ls[ic] =
     454                            int16bufs->rs[ic] = ((lt-rt)*23)>>5;
     455                        }
     456                    }
     457                    break;
     458                case 6:
     459                    for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     460                    {
     461                        int16bufs->l[ic] = *samples++ << 7;
     462                        int16bufs->c[ic] = *samples++ << 7;
     463                        int16bufs->r[ic] = *samples++ << 7;
     464                        int16bufs->ls[ic] = *samples++ << 7;
     465                        int16bufs->rs[ic] = *samples++ << 7;
     466                        int16bufs->lfe[ic] = *samples++ << 7;
     467                    }
     468                    break;
     469            }
     470            in_count = 0;
     471            out_count = ic;
     472            processed_size = ic;
     473            processed = false;
     474            break;
     475
     476        default:
     477            {
     478                float** inputs = decoder->getInputBuffers();
     479                float * lt = &inputs[0][ic];
     480                float * rt = &inputs[1][ic];
     481                if ((ic+numSamples) > bs)
     482                    numSamples = bs - ic;
     483                switch (numChannels)
     484                {
     485                    case 1:
     486                        for (i=0;i<numSamples;i++)
     487                        {
     488                            *lt++ =
     489                            *rt++ =
     490                                *samples++ MASTER_GAIN;
     491                        }
     492                        break;
     493                    case 2:
     494                        if (step>0)
     495                        {
     496                            for (i=0;i<numSamples;i++)
     497                            {
     498                                *lt++ = samples[0] MASTER_GAIN;
     499                                *rt++ = samples[step] MASTER_GAIN;
     500                                samples++;
     501                            }
     502                        }
     503                        else
     504                        {
     505                            for (i=0;i<numSamples;i++)
     506                            {
     507                                *lt++ = *samples++ MASTER_GAIN;
     508                                *rt++ = *samples++ MASTER_GAIN;
     509                            }
     510                        }
     511                        break;
     512                    case 6:
     513                        {
     514                        process = false;
     515                        short * l = &int16bufs->l[ic];
     516                        short * c = &int16bufs->c[ic];
     517                        short * r = &int16bufs->r[ic];
     518                        short * ls = &int16bufs->ls[ic];
     519                        short * rs = &int16bufs->rs[ic];
     520                        short * lfe = &int16bufs->lfe[ic];
     521                        for (i=0;i<numSamples;i++)
     522                        {
     523                            *l++ = *samples++ << 7;
     524                            *c++ = *samples++ << 7;
     525                            *r++ = *samples++ << 7;
     526                            *ls++ = *samples++ << 7;
     527                            *rs++ = *samples++ << 7;
     528                            *lfe++ = *samples++ << 7;
     529                        }
     530                        } break;
     531                }
     532                ic += numSamples;
     533                in_count = ic;
     534                processed = process;
     535                if (ic == bs)
     536                {
     537                    in_count = 0;
     538                    if (process)
     539                        process_block();
     540                    out_count = bs;
     541                    processed_size = bs;
     542                }
     543            } break;
     544    }
     545    VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5")
     546            .arg(numSamples)
     547            .arg(numChannels)
     548            .arg(step)
     549            .arg(i)
     550            .arg(out_count)
     551           );
     552    return i;
     553}
     554
     555uint FreeSurround::receiveSamples(
     556        short *output,
     557        uint maxSamples
     558        )
     559{
     560    uint i;
     561    uint oc = out_count;
     562    if (maxSamples>oc) maxSamples = oc;
     563    uint outindex = processed_size - oc;
     564    switch (surround_mode)
     565    {
     566        case SurroundModePassive:
     567            for (unsigned int i=0;i<maxSamples;i++)
     568            {
     569                *output++ = int16bufs->l[outindex];
     570                *output++ = int16bufs->r[outindex];
     571                *output++ = int16bufs->ls[outindex];
     572                *output++ = int16bufs->rs[outindex];
     573                *output++ = int16bufs->c[outindex];
     574                *output++ = int16bufs->lfe[outindex];
     575                oc--;
     576                outindex++;
     577            }
     578            break;
     579
     580        default:
     581            if (processed)
     582            {
     583                float** outputs = decoder->getOutputBuffers();
     584                float * l = &outputs[0][outindex];
     585                float * c = &outputs[1][outindex];
     586                float * r = &outputs[2][outindex];
     587                float * ls = &outputs[3][outindex];
     588                float * rs = &outputs[4][outindex];
     589                float * lfe = &outputs[5][outindex];
     590                for (unsigned int i=0;i<maxSamples;i++)
     591                {
     592                    *output++ = lrintf(*l++ INV_MASTER_GAIN);
     593                    *output++ = lrintf(*r++ INV_MASTER_GAIN);
     594                    *output++ = lrintf(*ls++ INV_MASTER_GAIN);
     595                    *output++ = lrintf(*rs++ INV_MASTER_GAIN);
     596                    *output++ = lrintf(*c++ INV_MASTER_GAIN);
     597                    *output++ = lrintf(*lfe++ INV_MASTER_GAIN);
     598                }
     599                oc -= maxSamples;
     600                outindex += maxSamples;
     601            }
     602            else
     603            {
     604                short * l = &int16bufs->l[outindex];
     605                short * c = &int16bufs->c[outindex];
     606                short * r = &int16bufs->r[outindex];
     607                short * ls = &int16bufs->ls[outindex];
     608                short * rs = &int16bufs->rs[outindex];
     609                short * lfe = &int16bufs->lfe[outindex];
     610                for (unsigned int i=0;i<maxSamples;i++)
     611                {
     612                    *output++ = *l++;
     613                    *output++ = *r++;
     614                    *output++ = *ls++;
     615                    *output++ = *rs++;
     616                    *output++ = *c++;
     617                    *output++ = *lfe++;
     618                }
     619                oc -= maxSamples;
     620                outindex += maxSamples;
     621            }
     622            break;
     623    }
     624    out_count = oc;
     625    VERBOSE1(QString("FreeSurround::receiveSamples %1")
     626            .arg(maxSamples)
     627           );
     628    return maxSamples;
     629}
     630
     631void FreeSurround::process_block()
     632{
     633    // process the data
     634    try
     635    {
     636        //float *input[2] = {&bufs->lt[0], &bufs->rt[0]};
     637        //float *output[8] = {&bufs->l[0], &bufs->c[0], &bufs->r[0], &bufs->ls[0], &bufs->rs[0], &bufs->lfe[0], &bufs->lcs[0], &bufs->rcs[0]};
     638        if (decoder)
     639        {
     640            // actually these params need only be set when they change... but it doesn't hurt
     641            decoder->steering_mode(params.steering);
     642            decoder->phase_mode(params.phasemode);
     643            decoder->surround_coefficients(params.coeff_a, params.coeff_b);                             
     644            decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
     645            // decode the bufs->block
     646            //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);
     647            //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);
     648            decoder->decode(params.center_width/100.0,params.dimension/100.0);
     649        }
     650    }
     651    catch(...)
     652    {
     653        //throw(std::runtime_error(std::string("error during processing (unsupported input format?)")));
     654    }
     655}
     656
     657long long FreeSurround::getLatency()
     658{
     659    // returns in usec
     660    if (surround_mode == SurroundModePassive)
     661        return 0;
     662    return decoder ? ((block_size/2 + in_count)*1000000)/(2*srate) : 0;
     663}
     664
     665void FreeSurround::flush()
     666{
     667    if (decoder)
     668        decoder->flush();
     669    int16bufs->clear();
     670}
     671
     672// load the lib and initialize the interface
     673void FreeSurround::open()
     674{               
     675    if (!decoder)
     676    {
     677        decoder = (fsurround_decoder*)dp.acquire((void*)1);
     678        decoder->flush();
     679        //if (bufs)
     680        //    bufs->clear();
     681        if (int16bufs)
     682            int16bufs->clear();
     683        decoder->sample_rate(srate);
     684    }
     685}
     686
     687void FreeSurround::close()
     688{
     689    if (decoder)
     690    {
     691        dp.release(this);
     692        decoder = 0;
     693    }
     694}
     695
     696uint FreeSurround::numUnprocessedSamples()
     697{
     698    return in_count;
     699}
     700
     701uint FreeSurround::numSamples()
     702{
     703    return out_count;
     704}
     705
     706uint FreeSurround::sampleLatency()
     707{
     708    if (processed)
     709        return in_count + out_count + (block_size/2);
     710    else
     711        return in_count + out_count;
     712}
     713
     714uint FreeSurround::samplesPerBlock()
     715{
     716    return block_size/2;
     717}
     718
  • 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
     58private:
     59
     60        // the changeable parameters
     61    struct fsurround_params {
     62        int32_t center_width;       // presence of the center channel
     63        int32_t dimension;                  // dimension
     64        float coeff_a,coeff_b;  // surround mixing coefficients
     65        int32_t phasemode;                      // phase shifting mode
     66        int32_t steering;                       // steering mode (0=simple, 1=linear)
     67        int32_t front_sep, rear_sep;// front/rear stereo separation
     68
     69        // (default) constructor
     70        fsurround_params(int32_t center_width=100, int32_t dimension=0);
     71    } params;
     72
     73        // additional settings
     74        uint srate;
     75
     76        // info about the current setup
     77        bool open_;                                     // whether a stream is currently open
     78        bool initialized_;                      // whether the thing is intialized     
     79        //struct buffers *bufs;                         // our buffers
     80        struct int16buffers *int16bufs;         // our buffers
     81        class fsurround_decoder *decoder;       // the surround decoder
     82    int in_count;               // amount in lt,rt
     83    int out_count;              // amount in output bufs
     84    bool processed;             // whether processing is enabled or not for latency calc
     85    int processed_size;         // amount processed
     86    SurroundMode surround_mode; // 1 of 3 surround modes supported
     87
     88};
     89
     90#endif
     91
  • 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 len = samples * audio_bytes_per_sample;
     652    int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
     653    int len = samples * abps;
    462654
    463655    // Check we have enough space to write the data
    464656    if (need_resampler && src_ctx)
    465657        len = (int)ceilf(float(len) * src_data.src_ratio);
    466658
     659    // include samples in upmix buffer that may be flushed
     660    if (needs_upmix && upmixer)
     661        len += upmixer->numUnprocessedSamples()*abps;
     662
     663    if (pSoundStretch)
     664        len += (pSoundStretch->numUnprocessedSamples() +
     665                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     666
    467667    if ((len > afree) && !blocking)
    468668    {
    469669        VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString(
     
    515715    // NOTE: This function is not threadsafe
    516716
    517717    int afree = audiofree(true);
    518     int len = samples * audio_bytes_per_sample;
     718    int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
     719    int len = samples * abps;
    519720
    520721    // Check we have enough space to write the data
    521722    if (need_resampler && src_ctx)
    522723        len = (int)ceilf(float(len) * src_data.src_ratio);
    523724
     725    // include samples in upmix buffer that may be flushed
     726    if (needs_upmix && upmixer)
     727        len += upmixer->numUnprocessedSamples()*abps;
     728 
     729    if (pSoundStretch)
     730        len += (pSoundStretch->numUnprocessedSamples() +
     731                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     732
    524733    if ((len > afree) && !blocking)
    525734    {
    526735        VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString(
    527736                "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
    528737                .arg(len).arg(AUDBUFSIZE-afree).arg(afree)
    529738                .arg(timecode));
    530 
    531739        return false; // would overflow
    532740    }
    533741
     
    564772
    565773int AudioOutputBase::WaitForFreeSpace(int samples)
    566774{
    567     int len = samples * audio_bytes_per_sample;
     775    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     776    int len = samples * abps;
    568777    int afree = audiofree(false);
     778    bool wait_min = true;
    569779
    570780    while (len > afree)
    571781    {
    572782        if (blocking)
    573783        {
    574             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     784            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    575785                    QString("(need %1, available %2)").arg(len).arg(afree));
    576786
    577787            // wait for more space
     
    580790        }
    581791        else
    582792        {
    583             VERBOSE(VB_IMPORTANT, LOC_ERR +
    584                     "Audio buffer overflow, audio data lost!");
    585             samples = afree / audio_bytes_per_sample;
    586             len = samples * audio_bytes_per_sample;
     793            if (wait_min)
     794            {
     795                // need to wait a fragment_size time best case
     796                int amount = len-afree;
     797                if (amount < fragment_size)
     798                    amount = fragment_size;
     799                int time_to_wait = (amount * 1000000LL)/(audio_samplerate * abps) + 5000;
     800                pthread_mutex_unlock(&audio_buflock);
     801                usleep(time_to_wait);
     802                pthread_mutex_lock(&audio_buflock);
     803                afree = audiofree(false);
     804                wait_min = false;               // do it once only
     805                continue;
     806            }
     807            VERBOSE(VB_IMPORTANT, LOC_ERR +
     808                    QString("Audio buffer overflow, %1 audio samples lost!")
     809                        .arg(samples - (afree / abps)));
     810            samples = afree / abps;
     811            len = samples * abps;
    587812            if (src_ctx)
    588813            {
    589814                int error = src_reset(src_ctx);
     
    608833   
    609834    int afree = audiofree(false);
    610835
    611     VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    612             LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4")
    613             .arg(samples * audio_bytes_per_sample)
    614             .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode));
     836    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     837    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     838            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6")
     839            .arg(samples)
     840            .arg(samples * abps)
     841            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     842            .arg(needs_upmix)
     843            );
    615844   
    616     len = WaitForFreeSpace(samples);
    617 
    618     if (interleaved)
     845    if (upmixer && needs_upmix)
    619846    {
    620         char *mybuf = (char*)buffer;
    621         int bdiff = AUDBUFSIZE - org_waud;
    622         if (bdiff < len)
     847        int out_samples = 0;
     848        int step = (interleaved)?source_audio_channels:1;
     849        len = WaitForFreeSpace(samples);    // test
     850        for(int itemp=0; itemp<samples; )
    623851        {
    624             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    625             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     852            // just in case it does a processing cycle, release the lock
     853            // to allow the output loop to do output
     854            pthread_mutex_unlock(&audio_buflock);
     855            if (audio_bytes == 2)
     856                itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     857            else
     858                itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     859            pthread_mutex_lock(&audio_buflock);
     860
     861            int copy_samples = upmixer->numSamples();
     862            if (copy_samples)
     863            {
     864                int copy_len = copy_samples * abps;
     865                out_samples += copy_samples;
     866                if (out_samples > samples)
     867                    len = WaitForFreeSpace(out_samples);
     868                int bdiff = AUDBUFSIZE - org_waud;
     869                if (bdiff < copy_len)
     870                {
     871                    int bdiff_samples = bdiff/abps;
     872                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples);
     873                    upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples));
     874                }
     875                else
     876                {
     877                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples);
     878                }
     879                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     880            }
    626881        }
    627         else
    628             memcpy(audiobuffer + org_waud, mybuf, len);
    629  
    630         org_waud = (org_waud + len) % AUDBUFSIZE;
    631     }
    632     else
     882        if (samples > 0)
     883        {
     884            len = WaitForFreeSpace(out_samples);
     885        }
     886        samples = out_samples;
     887    }
     888    else
    633889    {
    634         char **mybuf = (char**)buffer;
    635         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     890        len = WaitForFreeSpace(samples);
     891
     892        if (interleaved)
    636893        {
    637             for (int chan = 0; chan < audio_channels; chan++)
     894            char *mybuf = (char*)buffer;
     895            int bdiff = AUDBUFSIZE - org_waud;
     896            if (bdiff < len)
    638897            {
    639                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    640                 if (audio_bits == 16)
    641                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     898                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     899                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     900            }
     901            else
     902                memcpy(audiobuffer + org_waud, mybuf, len);
     903     
     904            org_waud = (org_waud + len) % AUDBUFSIZE;
     905        }
     906        else
     907        {
     908            char **mybuf = (char**)buffer;
     909            for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     910            {
     911                for (int chan = 0; chan < audio_channels; chan++)
     912                {
     913                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     914                    if (audio_bits == 16)
     915                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    642916
    643                 if (org_waud >= AUDBUFSIZE)
    644                     org_waud -= AUDBUFSIZE;
     917                    if (org_waud >= AUDBUFSIZE)
     918                        org_waud -= AUDBUFSIZE;
     919                }
    645920            }
    646921        }
    647922    }
    648923
    649     if (pSoundStretch)
     924    if (samples > 0)
    650925    {
    651         // does not change the timecode, only the number of samples
    652         // back to orig pos
    653         org_waud = waud;
    654         int bdiff = AUDBUFSIZE - org_waud;
    655         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
    656         if (bdiff < len)
     926        if (pSoundStretch)
    657927        {
    658             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    659                                       org_waud), nSamplesToEnd);
    660             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    661                                       (len - bdiff) / audio_bytes_per_sample);
    662         }
    663         else
    664         {
    665             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    666                                       org_waud), len / audio_bytes_per_sample);
    667         }
    668928
    669         int newLen = 0;
    670         int nSamples;
    671         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    672                                audio_bytes_per_sample);
    673         do
    674         {
    675             int samplesToGet = len/audio_bytes_per_sample;
    676             if (samplesToGet > nSamplesToEnd)
     929            // does not change the timecode, only the number of samples
     930            // back to orig pos
     931            org_waud = waud;
     932            int bdiff = AUDBUFSIZE - org_waud;
     933            int nSamplesToEnd = bdiff/abps;
     934            if (bdiff < len)
    677935            {
    678                 samplesToGet = nSamplesToEnd;   
     936                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     937                                          org_waud), nSamplesToEnd);
     938                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     939                                          (len - bdiff) / abps);
    679940            }
     941            else
     942            {
     943                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     944                                          org_waud), len / abps);
     945            }
    680946
    681             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    682                                       (audiobuffer + org_waud), samplesToGet);
    683             if (nSamples == nSamplesToEnd)
     947            if (encoder)
    684948            {
    685                 org_waud = 0;
    686                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     949                // pull out a packet's worth and reencode it until we dont have enough
     950                // for any more packets
     951                soundtouch::SAMPLETYPE* temp_buff =
     952                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     953                size_t frameSize = encoder->FrameSize()/abps;
     954                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     955                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     956                        .arg(frameSize)
     957                        .arg(encoder->FrameSize())
     958                        .arg(pSoundStretch->numSamples())
     959                       );
     960                // process the same number of samples as it creates a full encoded buffer
     961                // just like before
     962                while (pSoundStretch->numSamples() >= frameSize)
     963                {
     964                    int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     965                    int amount = encoder->Encode(temp_buff);
     966                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     967                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     968                            .arg(amount)
     969                            .arg(got)
     970                            .arg(pSoundStretch->numSamples())
     971                           );
     972                    if (amount == 0)
     973                        continue;
     974                    //len = WaitForFreeSpace(amount);
     975                    char * ob = encoder->GetOutBuff();
     976                    if (amount >= bdiff)
     977                    {
     978                        memcpy(audiobuffer + org_waud, ob, bdiff);
     979                        ob += bdiff;
     980                        amount -= bdiff;
     981                        org_waud = 0;
     982                    }
     983                    if (amount > 0)
     984                        memcpy(audiobuffer + org_waud, ob, amount);
     985                    bdiff = AUDBUFSIZE - amount;
     986                    org_waud += amount;
     987                }
    687988            }
    688989            else
    689990            {
    690                 org_waud += nSamples * audio_bytes_per_sample;
    691                 nSamplesToEnd -= nSamples;
     991                int newLen = 0;
     992                int nSamples;
     993                len = WaitForFreeSpace(pSoundStretch->numSamples() *
     994                                       audio_bytes_per_sample);
     995                do
     996                {
     997                    int samplesToGet = len/audio_bytes_per_sample;
     998                    if (samplesToGet > nSamplesToEnd)
     999                    {
     1000                        samplesToGet = nSamplesToEnd;   
     1001                    }
     1002
     1003                    nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     1004                                              (audiobuffer + org_waud), samplesToGet);
     1005                    if (nSamples == nSamplesToEnd)
     1006                    {
     1007                        org_waud = 0;
     1008                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1009                    }
     1010                    else
     1011                    {
     1012                        org_waud += nSamples * audio_bytes_per_sample;
     1013                        nSamplesToEnd -= nSamples;
     1014                    }
     1015
     1016                    newLen += nSamples * audio_bytes_per_sample;
     1017                    len -= nSamples * audio_bytes_per_sample;
     1018                } while (nSamples > 0);
    6921019            }
     1020        }
    6931021
    694             newLen += nSamples * audio_bytes_per_sample;
    695             len -= nSamples * audio_bytes_per_sample;
    696         } while (nSamples > 0);
    697     }
     1022        waud = org_waud;
     1023        lastaudiolen = audiolen(false);
    6981024
    699     waud = org_waud;
    700     lastaudiolen = audiolen(false);
     1025        if (timecode < 0)
     1026        {
     1027            // mythmusic doesn't give timestamps..
     1028            timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1029        }
     1030       
     1031        samples_buffered += samples;
     1032       
     1033        /* we want the time at the end -- but the file format stores
     1034           time at the start of the chunk. */
     1035        // even with timestretch, timecode is still calculated from original
     1036        // sample count
     1037        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7011038
    702     samples_buffered += samples;
    703    
    704     if (timecode < 0)
    705     {
    706         // mythmusic doesn't give timestamps..
    707         timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1039        if (interleaved)
     1040            dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits);
    7081041    }
    709    
    710     /* we want the time at the end -- but the file format stores
    711        time at the start of the chunk. */
    712     // even with timestretch, timecode is still calculated from original
    713     // sample count
    714     audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7151042
    716     if (interleaved)
    717         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    718 
    7191043    pthread_mutex_unlock(&audio_buflock);
    7201044}
    7211045
     
    7281052
    7291053    if (source_bitrate == -1)
    7301054    {
    731         source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1055        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
    7321056    }
    7331057
    7341058    if (ct / 1000 != current_seconds)
     
    7361060        current_seconds = ct / 1000;
    7371061        OutputEvent e(current_seconds, ct,
    7381062                      source_bitrate, audio_samplerate, audio_bits,
    739                       audio_channels);
     1063                      source_audio_channels);
    7401064        dispatch(e);
    7411065    }
    7421066}
     
    7691093            space_on_soundcard = getSpaceOnSoundcard();
    7701094
    7711095            if (space_on_soundcard != last_space_on_soundcard) {
    772                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1096                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7731097                        .arg(space_on_soundcard));
    7741098                last_space_on_soundcard = space_on_soundcard;
    7751099            }
     
    7821106                    WriteAudio(zeros, fragment_size);
    7831107                } else {
    7841108                    // this should never happen now -dag
    785                     VERBOSE(VB_AUDIO, LOC +
     1109                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    7861110                            QString("waiting for space on soundcard "
    7871111                                    "to write zeros: have %1 need %2")
    7881112                            .arg(space_on_soundcard).arg(fragment_size));
     
    8181142        if (fragment_size > audiolen(true))
    8191143        {
    8201144            if (audiolen(true) > 0)  // only log if we're sending some audio
    821                 VERBOSE(VB_AUDIO, LOC +
     1145                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8221146                        QString("audio waiting for buffer to fill: "
    8231147                                "have %1 want %2")
    8241148                        .arg(audiolen(true)).arg(fragment_size));
    8251149
    826             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1150            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8271151            pthread_mutex_lock(&audio_buflock);
    8281152            pthread_cond_broadcast(&audio_bufsig);
    8291153            pthread_mutex_unlock(&audio_buflock);
     
    8371161        if (fragment_size > space_on_soundcard)
    8381162        {
    8391163            if (space_on_soundcard != last_space_on_soundcard) {
    840                 VERBOSE(VB_AUDIO, LOC +
     1164                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8411165                        QString("audio waiting for space on soundcard: "
    8421166                                "have %1 need %2")
    8431167                        .arg(space_on_soundcard).arg(fragment_size));
     
    8991223
    9001224        /* update raud */
    9011225        raud = (raud + fragment_size) % AUDBUFSIZE;
    902         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1226        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9031227        pthread_cond_broadcast(&audio_bufsig);
    9041228
    9051229        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);
     
    36753678
    36763679void AvFormatDecoder::SetDisablePassThrough(bool disable)
    36773680{
     3681    // can only disable never reenable as once timestretch is on its on for the session
     3682    if (disable_passthru)
     3683        return;
    36783684    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    36793685    {
    36803686        disable_passthru = disable;
     
    37073713    AVCodecContext *codec_ctx = NULL;
    37083714    AudioInfo old_in  = audioIn;
    37093715    AudioInfo old_out = audioOut;
     3716    bool using_passthru = false;
    37103717
    37113718    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    37123719        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    37183725        assert(curstream->codec);
    37193726        codec_ctx = curstream->codec;       
    37203727        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3721                                 !disable_passthru &&
    37223728                                (codec_ctx->codec_id == CODEC_ID_AC3));
    37233729        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3724                                 !disable_passthru &&
    37253730                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3731        using_passthru = do_ac3_passthru || do_dts_passthru;
    37263732        info = AudioInfo(codec_ctx->codec_id,
    37273733                         codec_ctx->sample_rate, codec_ctx->channels,
    3728                          do_ac3_passthru || do_dts_passthru);
     3734                         using_passthru && !disable_passthru);
    37293735    }
    37303736
    37313737    if (info == audioIn)
    37323738        return false; // no change
    37333739
     3740    QString ptmsg = "";
     3741    if (using_passthru)
     3742    {
     3743        ptmsg = QString(" using passthru");
     3744    }
    37343745    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    37353746            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    37363747
    37373748    audioOut = audioIn = info;
    3738     if (audioIn.do_passthru)
     3749    if (using_passthru)
    37393750    {
    37403751        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3741         audioOut.channels    = 2;
    3742         audioOut.sample_rate = 48000;
    3743         audioOut.sample_size = 4;
     3752        AudioInfo digInfo = audioOut;
     3753        if (!disable_passthru)
     3754        {
     3755            digInfo.channels    = 2;
     3756            digInfo.sample_rate = 48000;
     3757            digInfo.sample_size = 4;
     3758        }
     3759        if (audioOut.channels > max_channels)
     3760        {
     3761            audioOut.channels = max_channels;
     3762            audioOut.sample_size = audioOut.channels * 2;
     3763            codec_ctx->channels = audioOut.channels;
     3764        }
     3765        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3766                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3767                .arg(digInfo.toString())
     3768                .arg(old_in.toString()).arg(old_out.toString())
     3769                .arg(audioIn.toString()).arg(audioOut.toString()));
     3770
     3771        if (digInfo.sample_rate > 0)
     3772            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3773
     3774        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3775                                 digInfo.sample_rate, audioIn.do_passthru);
     3776        // allow the audio stuff to reencode
     3777        GetNVP()->SetAudioCodec(codec_ctx);
     3778        GetNVP()->ReinitAudio();
     3779        return true;
    37443780    }
    37453781    else
    37463782    {
    3747         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3783        if (audioOut.channels > max_channels)
    37483784        {
    3749             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3785            audioOut.channels = max_channels;
    37503786            audioOut.sample_size = audioOut.channels * 2;
    3751             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3787            codec_ctx->channels = audioOut.channels;
    37523788        }
    37533789    }
     3790    bool audiook;
    37543791
    37553792    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    37563793            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    37633800    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    37643801                             audioOut.sample_rate,
    37653802                             audioIn.do_passthru);
    3766     GetNVP()->ReinitAudio();
     3803    // allow the audio stuff to reencode
     3804    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3805    QString errMsg = GetNVP()->ReinitAudio();
     3806    audiook = errMsg.isEmpty();
    37673807
    37683808    return true;
    37693809}
  • 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);
     
    13601362    CheckPrebuffering();
    13611363
    13621364    if ((play_speed > 1.01f) && (audio_stretchfactor > 1.01f) &&
    1363          livetv && IsNearEnd())
     1365         (livetv || (watchingrecording && nvr_enc && nvr_enc->IsValidRecorder()))
     1366         && IsNearEnd())
    13641367    {
    13651368        VERBOSE(VB_PLAYBACK, LOC + "Near end, Slowing down playback.");
    13661369        Play(1.0f, true, true);
     
    22772280            // decoding; display the frame, but don't wait for A/V Sync.
    22782281            videoOutput->PrepareFrame(buffer, kScan_Intr2ndField);
    22792282            videoOutput->Show(kScan_Intr2ndField);
    2280             VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait.");
     2283            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait.");
    22812284        }
    22822285        else
    22832286        {
    22842287            // If we are using software decoding, skip this frame altogether.
     2288            //VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame.");
    22852289            VERBOSE(VB_PLAYBACK, LOC + dbg + "dropping frame to catch up.");
    22862290        }
    22872291    }
     
    22912295        if (buffer)
    22922296            videoOutput->PrepareFrame(buffer, ps);
    22932297
     2298        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate));
    22942299        videosync->WaitForFrame(avsync_adjustment);
     2300        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
    22952301        if (!resetvideo)
    22962302            videoOutput->Show(ps);
    22972303
     
    23312337
    23322338            // Display the second field
    23332339            videosync->AdvanceTrigger();
    2334             videosync->WaitForFrame(0);
     2340            videosync->WaitForFrame(avsync_adjustment);
    23352341            if (!resetvideo)
    23362342            {
    23372343                videoOutput->Show(ps);
     
    23592365        // If audio is way behind of video, adjust for it...
    23602366        // by cutting the frame rate in half for the length of this frame
    23612367
    2362         avsync_adjustment = frame_interval;
     2368        //avsync_adjustment = frame_interval;
     2369        avsync_adjustment = refreshrate;
    23632370        lastsync = true;
    23642371        VERBOSE(VB_PLAYBACK, LOC +
    23652372                QString("Video is %1 frames ahead of audio,\n"
     
    23692376    if (audioOutput && normal_speed)
    23702377    {
    23712378        long long currentaudiotime = audioOutput->GetAudiotime();
    2372 #if 0
     2379#if 1
    23732380        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString(
    23742381                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    23752382                    "avdel %4 avg %5 tcoffset %6")
     
    27072714
    27082715    usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0);
    27092716
    2710     if ((print_verbose_messages & VB_PLAYBACK) != 0)
     2717    if ((print_verbose_messages & VB_PLAYBACK|VB_TIMESTAMP) == (VB_PLAYBACK|VB_TIMESTAMP))
    27112718        output_jmeter = new Jitterometer("video_output", 100);
    27122719    else
    27132720        output_jmeter = NULL;
     
    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)
     
    36963708        tc_avcheck_framecounter++;
    36973709        if (tc_avcheck_framecounter == 30)
    36983710        {
    3699 #define AUTO_RESYNC 1
     3711#define AUTO_RESYNC 0
    37003712#if AUTO_RESYNC
    37013713            // something's terribly, terribly wrong.
    37023714            if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 ||
  • 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;