Ticket #1104: mythtv_ac3.33.patch

File mythtv_ac3.33.patch, 100.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#pragma comment (lib,"libfftw3f-3.lib")
     26
     27typedef std::complex<float> cfloat;
     28
     29const float PI = 3.141592654;
     30const float epsilon = 0.000001;
     31const float center_level = 0.5*sqrt(0.5);       // gain of the center channel
     32
     33// private implementation of the surround decoder
     34class decoder_impl {
     35public:
     36        // create an instance of the decoder
     37        //  blocksize is fixed over the lifetime of this object for performance reasons
     38        decoder_impl(unsigned blocksize=8192): N(blocksize) {
     39                // create FFTW buffers
     40                lt = (float*)fftwf_malloc(sizeof(float)*N);
     41                rt = (float*)fftwf_malloc(sizeof(float)*N);
     42                dst = (float*)fftwf_malloc(sizeof(float)*N);
     43                dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     44                dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     45                src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N);
     46                loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE);
     47                loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE);
     48                store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE);       
     49                // resize our own buffers
     50                frontR.resize(N);
     51                frontL.resize(N);
     52                avg.resize(N);
     53                surR.resize(N);
     54                surL.resize(N);
     55                xfs.resize(N);
     56                yfs.resize(N);
     57                inbuf[0].resize(N + N/2);
     58                inbuf[1].resize(N + N/2);
     59                for (unsigned c=0;c<6;c++) {
     60                        outbuf[c].resize(N + N/2);
     61                        filter[c].resize(N);
     62                }
     63        // lfe filter is just straight through
     64                for (unsigned f=0;f<=N/2;f++) {                 
     65                        filter[5][f] = 1.0;
     66        }
     67                // generate the window function (square root of hann, b/c it is applied before and after the transform)
     68                wnd.resize(N);
     69                for (unsigned k=0;k<N;k++)
     70                        wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N)));
     71                // set the default coefficients
     72                surround_coefficients(0.8165,0.5774);
     73                phase_mode(0);
     74                separation(1,1);
     75                steering_mode(1);
     76        }
     77
     78        // destructor
     79        ~decoder_impl() {
     80                // clean up the FFTW stuff
     81                fftwf_destroy_plan(store);
     82                fftwf_destroy_plan(loadR);
     83                fftwf_destroy_plan(loadL);
     84                fftwf_free(src);
     85                fftwf_free(dftR);
     86                fftwf_free(dftL);
     87                fftwf_free(dst);
     88                fftwf_free(rt);
     89                fftwf_free(lt);
     90        }
     91
     92        // decode a chunk of stereo sound, has to contain exactly blocksize samples
     93        //  center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution
     94        //  dimension [0..1] moves the soundfield backwards, 0=front, 1=side
     95        //  adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption
     96        void decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) {
     97                // append incoming data to the end of the input buffer
     98                for (unsigned k=0;k<N;k++) {           
     99                        inbuf[0][k+N/2] = input[0][k];
     100                        inbuf[1][k+N/2] = input[1][k];
     101                }
     102                // process first part
     103                float *in_first[2] = {&inbuf[0][0],&inbuf[1][0]};
     104                add_output(in_first,output,center_width,dimension,adaption_rate);
     105                // process second part (overlapped) and return result
     106                float *in_second[2] = {&inbuf[0][N/2],&inbuf[1][N/2]};
     107                add_output(in_second,output,center_width,dimension,adaption_rate,true);
     108                // shift last third of input buffer to the beginning
     109                for (unsigned k=0;k<N/2;k++) {         
     110                        inbuf[0][k] = inbuf[0][k+N];
     111                        inbuf[1][k] = inbuf[1][k+N];
     112                }
     113        }
     114       
     115        // flush the internal buffers
     116        void flush() {
     117                for (unsigned k=0;k<N+N/2;k++) {
     118                        for (unsigned c=0;c<6;c++)
     119                                outbuf[c][k] = 0;
     120                        inbuf[0][k] = 0;
     121                        inbuf[1][k] = 0;
     122                }
     123        }
     124
     125        // set the assumed surround mixing coefficients
     126        void surround_coefficients(float a, float b) {
     127                master_gain = 1.0;
     128                // calc the simple coefficients
     129                surround_high = a;
     130                surround_low = b;
     131                surround_balance = (a-b)/(a+b);
     132                surround_level = 1/(a+b);
     133                // calc the linear coefficients
     134                cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0);
     135                A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n;
     136                E = (o+v)*n; F = (o+u)*n; G = (o-v)*n;  H = (o-u)*n;
     137        }
     138
     139        // set the phase shifting mode
     140        void phase_mode(unsigned mode) {
     141                const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}};
     142                phase_offsetL = modes[mode][0];
     143                phase_offsetR = modes[mode][1];
     144        }
     145
     146        // what steering mode should be chosen
     147        void steering_mode(bool mode) { linear_steering = mode; }
     148
     149        // set front & rear separation controls
     150        void separation(float front, float rear) {
     151                front_separation = front;
     152                rear_separation = rear;
     153        }
     154
     155private:
     156        // polar <-> cartesian coodinates conversion
     157        static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); }
     158        static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); }
     159        static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); }
     160        static inline float sqr(float x) { return x*x; }
     161        // the dreaded min/max
     162        static inline float min(float a, float b) { return a<b?a:b; }
     163        static inline float max(float a, float b) { return a>b?a:b; }
     164        static inline float clamp(float x) { return max(-1,min(1,x)); }
     165
     166        // handle the output buffering for overlapped calls of block_decode
     167        void add_output(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate, bool result=false) {
     168                // add the windowed data to the last 2/3 of the output buffer
     169                float *out[6] = {&outbuf[0][N/2],&outbuf[1][N/2],&outbuf[2][N/2],&outbuf[3][N/2],&outbuf[4][N/2],&outbuf[5][N/2]};
     170                block_decode(input,out,center_width,dimension,adaption_rate);
     171                for (unsigned c=0;c<6;c++) {
     172                        if (result)
     173                                // return the first 2/3 of the ouput buffer
     174                                for (unsigned k=0;k<N;k++)                             
     175                                        output[c][k] = outbuf[c][k];
     176                        for (unsigned k=0;k<N;k++)
     177                                // shift the last 2/3 to the first 2/3 of the output buffer
     178                                outbuf[c][k] = outbuf[c][k+N/2];
     179                        // and clear the rest
     180                        for (unsigned k=N;k<N+N/2;k++)
     181                                outbuf[c][k] = 0;
     182                }
     183        }
     184
     185        // CORE FUNCTION: decode a block of data
     186        void block_decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) {
     187                // 1. scale the input by the window function; this serves a dual purpose:
     188                // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed
     189                // - second it allows for smooth blending of varying filters between the blocks
     190                for (unsigned k=0;k<N;k++) {
     191                        lt[k] = input[0][k] * wnd[k] * master_gain;
     192                        rt[k] = input[1][k] * wnd[k] * master_gain;
     193                }
     194
     195                // ... and tranform it into the frequency domain
     196                fftwf_execute(loadL);
     197                fftwf_execute(loadR);
     198
     199                // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
     200                for (unsigned f=0;f<=N/2;f++) {                 
     201                        // get left/right amplitudes/phases
     202                        float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
     203                        float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
     204//                      if (ampL+ampR < epsilon)
     205//                              continue;               
     206
     207                        // calculate the amplitude/phase difference
     208                        float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
     209                        float phaseDiff = phaseL - phaseR;
     210                        if (phaseDiff < -PI) phaseDiff += 2*PI;
     211                        if (phaseDiff > PI) phaseDiff -= 2*PI;
     212                        phaseDiff = abs(phaseDiff);
     213
     214                        if (linear_steering) {
     215/*                              cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);
     216                                cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w;                              */
     217//                              xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();
     218//                              yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);
     219
     220                                /*
     221                                Problem:
     222                                This assumes that the values are interpolated linearly between the cardinal points.
     223                                But this way we have no chance of knowing the average volume...
     224                                - Can we solve that computing everything under the assumption of normalized volume?
     225                                  No. Seemingly not.
     226                                - Maybe we should add w explitcitly into the equation and see if we can solve it...
     227                                */
     228
     229
     230                                //cfloat lt(0.5,0),rt(0.5,0);
     231                                //cfloat x(0,0), y(1,0);
     232                                /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);
     233                                cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);
     234                                cfloat s = sqrt(p*p/4.0f - q);
     235                                cfloat x = -p;
     236                                cfloat x1 = -p/2.0f + s;
     237                                cfloat x2 = -p/2.0f - s;
     238                                float x = 0;
     239                                if (x1.real() >= -1 && x1.real() <= 1)
     240                                        x = x1.real();
     241                                else if (x2.real() >= -1 && x2.real() <= 1)
     242                                        x = x2.real();*/
     243
     244                                //cfloat yp = (rt - (x*E+H))/(F+x*G);
     245                                //cfloat xp = (lt - (y*B+D))/(A+y*C);
     246
     247                                /*xfs[f] = x;
     248                                yfs[f] = y.real();*/
     249
     250                                // --- this is the fancy new linear mode ---
     251
     252                                // get sound field x/y position
     253                                yfs[f] = get_yfs(ampDiff,phaseDiff);
     254                                xfs[f] = get_xfs(ampDiff,yfs[f]);
     255
     256                                // add dimension control
     257                                yfs[f] = clamp(yfs[f] - dimension);
     258
     259                                // add crossfeed control
     260                                xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
     261
     262                                // 3. generate frequency filters for each output channel
     263                                float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
     264                                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
     265                                float volume[5] = {
     266                                        front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),      // left
     267                                        front * center_level*((1-abs(xfs[f])) * (1-center_width)),                      // center
     268                                        front * (right * center_width + max(0, xfs[f]) * (1-center_width)),     // right
     269                                        back * surround_level * left,                                                                           // left surround
     270                                        back * surround_level * right                                                                           // right surround
     271                                };
     272
     273                                // adapt the prior filter
     274                                for (unsigned c=0;c<5;c++)
     275                                        filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N;
     276
     277                        } else {
     278                                // --- this is the old & simple steering mode ---
     279
     280                                // calculate the amplitude/phase difference
     281                                float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL));
     282                                float phaseDiff = phaseL - phaseR;
     283                                if (phaseDiff < -PI) phaseDiff += 2*PI;
     284                                if (phaseDiff > PI) phaseDiff -= 2*PI;
     285                                phaseDiff = abs(phaseDiff);
     286
     287                                // determine sound field x-position
     288                                xfs[f] = ampDiff;
     289
     290                                // determine preliminary sound field y-position from phase difference
     291                                yfs[f] = 1 - (phaseDiff/PI)*2;
     292
     293                                if (abs(xfs[f]) > surround_balance) {
     294                                        // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance
     295                                        // this is necessary because the sound field is trapezoidal and will be stretched behind the listener
     296                                        float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance);
     297                                        yfs[f]  = (1-frontness) * yfs[f] + frontness * 1;
     298                                }
     299
     300                                // add dimension control
     301                                yfs[f] = clamp(yfs[f] - dimension);
     302
     303                                // add crossfeed control
     304                                xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2));
     305
     306                                // 3. generate frequency filters for each output channel, according to the signal position
     307                                // the sum of all channel volumes must be 1.0
     308                                float left = (1-xfs[f])/2, right = (1+xfs[f])/2;
     309                                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
     310                                float volume[5] = {
     311                                        front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),              // left
     312                                        front * center_level*((1-abs(xfs[f])) * (1-center_width)),                              // center
     313                                        front * (right * center_width + max(0, xfs[f]) * (1-center_width)),             // right
     314                                        back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))),  // left surround
     315                                        back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2)))   // right surround
     316                                };
     317
     318                                // adapt the prior filter
     319                                for (unsigned c=0;c<5;c++)
     320                                        filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N;
     321                        }
     322
     323                        // ... and build the signal which we want to position
     324                        frontL[f] = polar(ampL+ampR,phaseL);
     325                        frontR[f] = polar(ampL+ampR,phaseR);
     326                        avg[f] = frontL[f] + frontR[f];
     327                        surL[f] = polar(ampL+ampR,phaseL+phase_offsetL);
     328                        surR[f] = polar(ampL+ampR,phaseR+phase_offsetR);
     329                }
     330
     331                // 4. distribute the unfiltered reference signals over the channels
     332                apply_filter(&frontL[0],&filter[0][0],&output[0][0]);   // front left
     333                apply_filter(&avg[0], &filter[1][0],&output[1][0]);             // front center
     334                apply_filter(&frontR[0],&filter[2][0],&output[2][0]);   // front right
     335                apply_filter(&surL[0],&filter[3][0],&output[3][0]);             // surround left
     336                apply_filter(&surR[0],&filter[4][0],&output[4][0]);             // surround right
     337                apply_filter(&avg[0],&filter[5][0],&output[5][0]);              // lfe
     338        }
     339
     340        // map from amplitude difference and phase difference to yfs
     341        inline double get_yfs(double ampDiff, double phaseDiff) {
     342                double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2);
     343                return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x
     344                        + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x));
     345        }
     346
     347        // map from amplitude difference and yfs to xfs
     348        inline double get_xfs(double ampDiff, double yfs) {
     349                double x=ampDiff,y=yfs;
     350                return 2.464833559224702*x - 423.52131153259404*x*y +
     351                        67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y -
     352                        79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y +
     353                        35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) -
     354                        2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) -
     355                        12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) +
     356                        1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) +
     357                        12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) -
     358                        91.21223198407546*tan(x)*tan(y);
     359        }
     360
     361        // filter the complex source signal and add it to target
     362        void apply_filter(cfloat *signal, float *flt, float *target) {
     363                // filter the signal
     364                for (unsigned f=0;f<=N/2;f++) {         
     365                        src[f][0] = signal[f].real() * flt[f];
     366                        src[f][1] = signal[f].imag() * flt[f];
     367                }
     368                // transform into time domain
     369                fftwf_execute(store);
     370                // add the result to target, windowed
     371                for (unsigned k=0;k<N;k++)
     372                        target[k] += wnd[k]*dst[k];
     373        }
     374
     375        unsigned N;                                                // the block size
     376        // FFTW data structures
     377        float *lt,*rt,*dst;                                // left total, right total (source arrays), destination array
     378        fftwf_complex *dftL,*dftR,*src;    // intermediate arrays (FFTs of lt & rt, processing source)
     379        fftwf_plan loadL,loadR,store;      // plans for loading the data into the intermediate format and back
     380        // buffers
     381        std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain
     382        std::vector<float> xfs,yfs;                // the feature space positions for each frequency bin
     383        std::vector<float> wnd;                    // the window function, precalculated
     384        std::vector<float> filter[6];      // a frequency filter for each output channel
     385        std::vector<float> inbuf[2];       // the sliding input buffers
     386        std::vector<float> outbuf[6];      // the sliding output buffers
     387        // coefficients
     388        float surround_high,surround_low;  // high and low surround mixing coefficient (e.g. 0.8165/0.5774)
     389        float surround_balance;                    // the xfs balance that follows from the coeffs
     390        float surround_level;                      // gain for the surround channels (follows from the coeffs
     391        float master_gain;                                 // gain for all channels
     392        float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels
     393        float front_separation;                    // front stereo separation
     394        float rear_separation;                     // rear stereo separation
     395        bool linear_steering;                      // whether the steering should be linear or not
     396        cfloat A,B,C,D,E,F,G,H;                    // coefficients for the linear steering
     397};
     398
     399
     400// implementation of the shell class
     401
     402fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { }
     403
     404fsurround_decoder::~fsurround_decoder() { delete impl; }
     405
     406void fsurround_decoder::decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) {
     407        impl->decode(input,output,center_width,dimension,adaption_rate);
     408}
     409
     410void fsurround_decoder::flush() { impl->flush(); }
     411
     412void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); }
     413
     414void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); }
     415
     416void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); }
     417
     418void fsurround_decoder::separation(float front, float rear) { impl->separation(front,rear); }
  • 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        // decode a chunk of stereo sound, has to contain exactly blocksize samples
     32        //  center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution
     33        //  dimension [0..1] moves the soundfield backwards, 0=front, 1=side
     34        //  adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption
     35        void decode(float *input[2], float *output[6], float center_width=1, float dimension=0, float adaption_rate=1);
     36       
     37        // flush the internal buffers
     38        void flush();
     39
     40        // --- advanced configuration ---
     41
     42        // override the surround coefficients
     43        //  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.
     44        void surround_coefficients(float a, float b);
     45
     46        // set the phase shifting mode for decoding
     47        // 0 = (+0°,+0°)   - music mode
     48        // 1 = (+0°,+180°) - PowerDVD compatibility
     49        // 2 = (+180°,+0°) - BeSweet compatibility
     50        // 3 = (-90°,+90°) - This seems to work. I just don't know why.
     51        void phase_mode(unsigned mode);
     52
     53        // override the steering mode
     54        //  false = simple non-linear steering (old)
     55        //  true  = advanced linear steering (new)
     56        void steering_mode(bool mode);
     57
     58        // set front/rear stereo separation
     59        //  1.0 is default, 0.0 is mono
     60        void separation(float front,float rear);
     61private:
     62        class decoder_impl *impl; // private implementation (details hidden)
     63};
     64
     65
     66#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
     31#include <qstring.h>
     32#include <qdatetime.h>
     33
     34using namespace std;
     35
     36#if 0
     37#define VERBOSE(args...) \
     38    do { \
     39        QDateTime dtmp = QDateTime::currentDateTime(); \
     40        QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \
     41        ostringstream verbose_macro_tmp; \
     42        verbose_macro_tmp << dtime << " " << args; \
     43        cout << verbose_macro_tmp.str() << endl; \
     44    } while (0)
     45#else
     46#define VERBOSE(args...)
     47#endif
     48#if 0
     49#define VERBOSE1(args...) \
     50    do { \
     51        QDateTime dtmp = QDateTime::currentDateTime(); \
     52        QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \
     53        ostringstream verbose_macro_tmp; \
     54        verbose_macro_tmp << dtime << " " << args; \
     55        cout << verbose_macro_tmp.str() << endl; \
     56    } while (0)
     57#else
     58#define VERBOSE1(args...)
     59#endif
     60
     61// our default internal block size, in floats
     62const unsigned block_size = 8192;
     63// there will be a slider for this in the future
     64const float master_gain = 1.0;
     65
     66unsigned bs = block_size;
     67
     68// stupidity countermeasure...
     69template<class T> T pop_back(std::list<T> &l) { T result(l.back()); l.pop_back(); return result; }
     70
     71// a pool, where the DSP can throw its objects at after it got deleted and get them back when it is recreated...
     72class object_pool {
     73public:
     74        typedef void* (*callback)();
     75    typedef std::map< void* , void* > map_t;
     76    typedef map_t::iterator mapiterator;
     77        // initialize
     78        object_pool(callback cbf):construct(cbf) { }
     79        ~object_pool() {
     80                for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();i!=e;i++)
     81                //for (mapiterator i=pool.begin(),e=pool.end();i!=e;i++)
     82                        delete i->second;
     83                for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();i!=e;i++)
     84                        delete *i;
     85        }
     86        // (re)acquire an object
     87        void *acquire(void *who) {
     88                std::map<void*,void*>::iterator i(pool.find(who));
     89                if (i != pool.end())
     90                        return i->second;
     91                else
     92                        if (!freelist.empty())
     93                                return pool.insert(std::make_pair(who,pop_back(freelist))).first->second;
     94                        else
     95                                return pool.insert(std::make_pair(who,construct())).first->second;
     96        }
     97        // release an object into the wild
     98        void release(void *who) {
     99                std::map<void*,void*>::iterator i(pool.find(who));
     100                if (i != pool.end()) {
     101                        freelist.push_back(i->second);
     102                        pool.erase(i);
     103                }
     104        }       
     105public:
     106        callback construct;                     // object constructor callback
     107        std::list<void*> freelist;              // list of available objects
     108        std::map<void*,void*> pool;     // pool of used objects, by class
     109};
     110
     111// buffers which we usually need (and want to share between plugin lifespans)
     112struct buffers {
     113        buffers(unsigned int s):
     114        //block(),result(s),
     115        lt(s),rt(s),
     116        l(s),r(s),c(s),ls(s),rs(s),lfe(s),cs(s),lcs(s),rcs(s) { }
     117        void resize(unsigned int s) {
     118                lt.resize(s); rt.resize(s); l.resize(s); r.resize(s); lfe.resize(s);
     119                ls.resize(s); rs.resize(s); c.resize(s); cs.resize(s); lcs.resize(s); rcs.resize(s);
     120        }
     121        void clear() {
     122                lt.clear(); rt.clear(); l.clear(); r.clear();
     123                ls.clear(); rs.clear(); c.clear();
     124                //block.clear(); result.clear();
     125        }
     126        //std::vector<short> block,result;                              // for buffering
     127        std::vector<float> lt,rt;                                               // for multiplexing
     128        std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs;  // for demultiplexing
     129};
     130
     131// construction methods
     132void *new_decoder() { return new fsurround_decoder(block_size); }
     133void *new_buffers() { return new buffers(bs); }
     134
     135object_pool dp(&new_decoder);
     136object_pool bp(&new_buffers);
     137
     138//#define SPEAKERTEST
     139#ifdef SPEAKERTEST
     140int channel_select = -1;
     141#endif
     142
     143FreeSurround::FreeSurround(uint srate, bool moviemode) :
     144        srate(srate),
     145        open_(false),
     146        initialized_(false),
     147        bufs((buffers*)bp.acquire(this)),
     148        decoder(0),
     149        in_count(0),
     150        out_count(0),
     151        processed(true)
     152{
     153    VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode));
     154    if (moviemode)
     155    {
     156        params.phasemode = 1;
     157        params.center_width = 0;
     158    }
     159    open();
     160#ifdef SPEAKERTEST
     161    channel_select++;
     162    if (channel_select>=6)
     163        channel_select = 0;
     164    VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select));
     165#endif
     166
     167    VERBOSE(QString("FreeSurround::FreeSurround done"));
     168}
     169
     170FreeSurround::fsurround_params::fsurround_params(
     171        int32_t center_width,
     172        int32_t dimension
     173    ) :
     174    center_width(center_width),
     175    dimension(dimension),
     176    coeff_a(0.8165),coeff_b(0.5774),
     177    phasemode(0),
     178    steering(1),
     179    front_sep(100),
     180    rear_sep(100)
     181{
     182}
     183
     184FreeSurround::~FreeSurround()
     185{
     186    VERBOSE(QString("FreeSurround::~FreeSurround"));
     187    close();
     188    bp.release(this);
     189    VERBOSE(QString("FreeSurround::~FreeSurround done"));
     190}
     191
     192uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step)
     193{
     194    int i;
     195    int ic = in_count;
     196    int bs = block_size;
     197    bool process = true;
     198    // demultiplex
     199    switch (numChannels)
     200    {
     201        case 1:
     202            for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     203            {
     204                bufs->lt[ic] =
     205                bufs->rt[ic] =
     206                    samples[i]*master_gain;
     207            }
     208            break;
     209        case 2:
     210            if (step>0)
     211            {
     212                for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     213                {
     214                    bufs->lt[ic] = samples[i]*master_gain;
     215                    bufs->rt[ic] = samples[i+step]*master_gain;
     216                }
     217            }
     218            else
     219            {
     220                for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     221                {
     222                    bufs->lt[ic] = samples[i*2]*master_gain;
     223                    bufs->rt[ic] = samples[i*2+1]*master_gain;
     224                }
     225            }
     226            break;
     227        case 6:
     228            process = false;
     229            for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     230            {
     231                bufs->l[ic] = *samples++;
     232                bufs->c[ic] = *samples++;
     233                bufs->r[ic] = *samples++;
     234                bufs->ls[ic] = *samples++;
     235                bufs->rs[ic] = *samples++;
     236                bufs->lfe[ic] = *samples++;
     237            }
     238            break;
     239    }
     240    in_count = ic;
     241    processed = process;
     242    if (ic == bs)
     243    {
     244        in_count = 0;
     245        if (process)
     246            process_block();
     247        out_count = bs;
     248    }
     249    VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5")
     250            .arg(numSamples)
     251            .arg(numChannels)
     252            .arg(step)
     253            .arg(i)
     254            .arg(out_count)
     255           );
     256    return i;
     257}
     258
     259uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step)
     260{
     261    int i;
     262    int ic = in_count;
     263    int bs = block_size;
     264    bool process = true;
     265    // demultiplex
     266    switch (numChannels)
     267    {
     268        case 1:
     269            for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     270            {
     271                bufs->lt[ic] =
     272                bufs->rt[ic] =
     273                    samples[i]*master_gain;
     274            }
     275            break;
     276        case 2:
     277            if (step>0)
     278            {
     279                for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     280                {
     281                    bufs->lt[ic] = samples[i]*master_gain;
     282                    bufs->rt[ic] = samples[i+step]*master_gain;
     283                }
     284            }
     285            else
     286            {
     287                for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     288                {
     289                    bufs->lt[ic] = samples[i*2]*master_gain;
     290                    bufs->rt[ic] = samples[i*2+1]*master_gain;
     291                }
     292            }
     293            break;
     294        case 6:
     295            process = false;
     296            for (i=0;(i<numSamples) && (ic < bs);i++,ic++)
     297            {
     298                bufs->l[ic] = *samples++;
     299                bufs->c[ic] = *samples++;
     300                bufs->r[ic] = *samples++;
     301                bufs->ls[ic] = *samples++;
     302                bufs->rs[ic] = *samples++;
     303                bufs->lfe[ic] = *samples++;
     304            }
     305            break;
     306    }
     307    in_count = ic;
     308    processed = process;
     309    if (ic == bs)
     310    {
     311        in_count = 0;
     312        if (process)
     313            process_block();
     314        out_count = bs;
     315    }
     316    VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5")
     317            .arg(numSamples)
     318            .arg(numChannels)
     319            .arg(step)
     320            .arg(i)
     321            .arg(out_count)
     322           );
     323    return i;
     324}
     325
     326uint FreeSurround::receiveSamples(
     327        short *output,
     328        uint maxSamples
     329        )
     330{
     331    uint i;
     332    uint oc = out_count;
     333    if (maxSamples>oc) maxSamples = oc;
     334    uint outindex = block_size - oc;
     335    for (unsigned int i=0;i<maxSamples;i++)
     336    {
     337#ifndef BYPASS
     338#ifdef SPEAKERTEST
     339        *output++ = (channel_select==0)?(short)bufs->l[outindex]:0; //L
     340        *output++ = (channel_select==1)?(short)bufs->r[outindex]:0; //R
     341        *output++ = (channel_select==2)?(short)bufs->c[outindex]:0; //LS
     342        *output++ = (channel_select==3)?(short)bufs->c[outindex]:0; //RS
     343        *output++ = (channel_select==4)?(short)bufs->c[outindex]:0; //C
     344        *output++ = (channel_select==5)?(short)bufs->c[outindex]:0; //LFE
     345#else
     346        *output++ = (short)bufs->l[outindex];
     347        *output++ = (short)bufs->r[outindex];
     348        *output++ = (short)bufs->ls[outindex];
     349        *output++ = (short)bufs->rs[outindex];
     350        *output++ = (short)bufs->c[outindex];
     351        *output++ = (short)bufs->lfe[outindex];
     352#endif
     353#else
     354        *output++ = (short)bufs->lt[outindex];
     355        *output++ = (short)bufs->rt[outindex];
     356        *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7);
     357        *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7);
     358        *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5);
     359        *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5);
     360#endif
     361        oc--;
     362        outindex++;
     363    }
     364    out_count = oc;
     365    VERBOSE1(QString("FreeSurround::receiveSamples %1")
     366            .arg(maxSamples)
     367           );
     368    return maxSamples;
     369}
     370
     371void FreeSurround::process_block()
     372{
     373#ifndef BYPASS
     374    // process the data
     375    try {
     376        float *input[2] = {&bufs->lt[0], &bufs->rt[0]};
     377        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]};
     378        if (decoder) {
     379            // actually these params need only be set when they change... but it doesn't hurt
     380            decoder->steering_mode(params.steering);
     381            decoder->phase_mode(params.phasemode);
     382            decoder->surround_coefficients(params.coeff_a, params.coeff_b);                             
     383            decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
     384            // decode the bufs->block
     385            decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);
     386        }
     387    } catch(...) {
     388        //throw(std::runtime_error(std::string("error during processing (unsupported input format?)")));
     389    }
     390#endif
     391}
     392
     393long long FreeSurround::getLatency()
     394{
     395    // returns in usec
     396    return decoder ? ((block_size + in_count)*1000000)/(2*srate) : 0;
     397}
     398
     399void FreeSurround::flush() {
     400    if (decoder)
     401        decoder->flush();
     402    bufs->clear();
     403}
     404
     405// load the lib and initialize the interface
     406void FreeSurround::open()
     407{               
     408    if (!decoder) {
     409        decoder = (fsurround_decoder*)dp.acquire(this);
     410        decoder->flush();
     411        bufs->clear();
     412    }
     413}
     414
     415void FreeSurround::close()
     416{
     417    if (decoder) {
     418        dp.release(this);
     419        decoder = 0;
     420    }
     421}
     422
     423uint FreeSurround::numUnprocessedSamples()
     424{
     425    return in_count;
     426}
     427
     428uint FreeSurround::numSamples()
     429{
     430    return out_count;
     431}
     432
     433uint FreeSurround::sampleLatency()
     434{
     435    if (processed)
     436        return in_count + out_count + (block_size/2);
     437    else
     438        return in_count + out_count;
     439}
     440
  • 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
     22#include <systems.h>
     23
     24class FreeSurround
     25{
     26public:
     27    FreeSurround(uint srate, bool moviemode);
     28    ~FreeSurround();
     29
     30    // put samples in buffer, returns number of samples used
     31    uint putSamples(short* samples, uint numSamples, uint numChannels, int step);
     32    uint putSamples(char* samples, uint numSamples, uint numChannels, int step);
     33    // get a number of samples
     34    uint receiveSamples(short *output,
     35                        uint maxSamples
     36                        );
     37    // flush unprocessed samples
     38    void flush();
     39    //void setSampleRate(uint srate);
     40    uint numUnprocessedSamples();
     41    uint numSamples();
     42
     43    long long getLatency();
     44    uint sampleLatency();
     45
     46protected:
     47    void process_block();
     48    void open();
     49    void close();
     50
     51private:
     52
     53        // the changeable parameters
     54    struct fsurround_params {
     55        int32_t center_width;       // presence of the center channel
     56        int32_t dimension;                  // dimension
     57        float coeff_a,coeff_b;  // surround mixing coefficients
     58        int32_t phasemode;                      // phase shifting mode
     59        int32_t steering;                       // steering mode (0=simple, 1=linear)
     60        int32_t front_sep, rear_sep;// front/rear stereo separation
     61
     62        // (default) constructor
     63        fsurround_params(int32_t center_width=100, int32_t dimension=0);
     64    } params;
     65
     66        // additional settings
     67        uint srate;
     68
     69        // info about the current setup
     70        bool open_;                                     // whether a stream is currently open
     71        bool initialized_;                      // whether the thing is intialized     
     72        struct buffers *bufs;                           // our buffers
     73        class fsurround_decoder *decoder;       // the surround decoder
     74    int in_count;               // amount in lt,rt
     75    int out_count;              // amount in output bufs
     76    bool processed;             // whether processing is enabled or not for latency calc
     77
     78};
     79
     80#endif
     81
  • 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
     23LIBS += -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);
    3842
     
    7478        lastError = msg;
    7579        VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError);
    7680    }
     81    void ClearError()
     82     { lastError = QString::null; };
    7783
    7884    void Warn(QString msg)
    7985    {
  • 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);
     
    125138    bool audio_passthru;
    126139
    127140    float audio_stretchfactor;
     141    AVCodecContext *audio_codec;
    128142    AudioOutputSource source;
    129143
    130144    bool killaudio;
     
    133147    bool set_initial_vol;
    134148    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    135149   
     150    int configured_audio_channels;
     151
    136152 private:
    137153    // resampler
    138154    bool need_resampler;
     
    144160
    145161    // timestretch
    146162    soundtouch::SoundTouch * pSoundStretch;
     163    AudioOutputDigitalEncoder * encoder;
     164    FreeSurround * upmixer;
    147165
     166    int source_audio_channels;
     167    int source_audio_bytes_per_sample;
     168    bool needs_upmix;
     169
    148170    bool blocking; // do AddSamples calls block?
    149171
    150172    int lastaudiolen;
     
    162184
    163185    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    164186                                    'audiotime' and 'audiotime_updated' */
    165     int audiotime; // timecode of audio leaving the soundcard (same units as
     187    long long audiotime; // timecode of audio leaving the soundcard (same units as
    166188                   //                                          timecodes) ...
    167189    struct timeval audiotime_updated; // ... which was last updated at this time
    168190
    169191    /* Audio circular buffer */
    170192    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    171193    int raud, waud;     /* read and write positions */
    172     int audbuf_timecode;    /* timecode of audio most recently placed into
     194    long long audbuf_timecode;    /* timecode of audio most recently placed into
    173195                   buffer */
    174196
    175197    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),
    5160
     61    blocking(false),
     62
    5263    lastaudiolen(0),            samples_buffered(0),
    5364
    5465    audio_thread_exists(false),
     
    7182    memset(tmp_buff,           0, sizeof(short) * AUDIO_TMP_BUF_SIZE);
    7283    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    7384    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
     85    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    7486
    7587    // You need to call Reconfigure from your concrete class.
    7688    // Reconfigure(laudio_bits,       laudio_channels,
     
    111123            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    112124                                        .arg(audio_stretchfactor));
    113125            pSoundStretch = new soundtouch::SoundTouch();
    114             pSoundStretch->setSampleRate(audio_samplerate);
    115             pSoundStretch->setChannels(audio_channels);
     126            if (audio_codec)
     127            {
     128                if (!encoder)
     129                {
     130                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     131                    encoder = new AudioOutputDigitalEncoder();
     132                    if (!encoder->Init(audio_codec->codec_id,
     133                                audio_codec->bit_rate,
     134                                audio_codec->sample_rate,
     135                                audio_codec->channels
     136                                ))
     137                    {
     138                        // eeks
     139                        delete encoder;
     140                        encoder = NULL;
     141                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     142                    }
     143                }
     144            }
     145            if (encoder)
     146            {
     147                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     148                pSoundStretch->setChannels(audio_codec->channels);
     149            }
     150            else
     151            {
     152                pSoundStretch->setSampleRate(audio_samplerate);
     153                pSoundStretch->setChannels(audio_channels);
     154            }
    116155
    117156            pSoundStretch->setTempo(audio_stretchfactor);
    118157            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    135174}
    136175
    137176void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    138                                  int laudio_samplerate, bool laudio_passthru)
     177                                 int laudio_samplerate, bool laudio_passthru,
     178                                 void* laudio_codec)
    139179{
     180    int codec_id = CODEC_ID_NONE;
     181    int lcodec_id = CODEC_ID_NONE;
     182    int lcchannels = 0;
     183    int cchannels = 0;
     184    int lsource_audio_channels = laudio_channels;
     185    bool lneeds_upmix = false;
     186
     187    if (laudio_codec)
     188    {
     189        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     190        laudio_bits = 16;
     191        laudio_channels = 2;
     192        lsource_audio_channels = laudio_channels;
     193        laudio_samplerate = 48000;
     194        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     195    }
     196    if (audio_codec)
     197    {
     198        codec_id = audio_codec->codec_id;
     199        cchannels = ((AVCodecContext*)audio_codec)->channels;
     200    }
     201    if ((configured_audio_channels == 6) &&
     202        //(configured_audio_channels != lsource_audio_channels) &&
     203        !(laudio_codec || audio_codec))
     204    {
     205        laudio_channels = configured_audio_channels;
     206        lneeds_upmix = true;
     207        VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     208    }
     209    ClearError();
    140210    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     211        laudio_samplerate == audio_samplerate && !need_resampler &&
     212        laudio_passthru == audio_passthru &&
     213        lneeds_upmix == needs_upmix &&
     214        lcodec_id == codec_id && lcchannels == cchannels)
     215    {
     216        VERBOSE(VB_AUDIO,LOC + "no change exiting");
    143217        return;
    144 
     218    }
    145219    KillAudio();
    146220   
    147221    pthread_mutex_lock(&audio_buflock);
     
    151225    waud = raud = 0;
    152226    audio_actually_paused = false;
    153227   
     228    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154229    audio_channels = laudio_channels;
     230    source_audio_channels = lsource_audio_channels;
    155231    audio_bits = laudio_bits;
    156232    audio_samplerate = laudio_samplerate;
     233    audio_codec = (AVCodecContext*)laudio_codec;
    157234    audio_passthru = laudio_passthru;
     235    needs_upmix = lneeds_upmix;
    158236    if (audio_bits != 8 && audio_bits != 16)
    159237    {
    160238        pthread_mutex_unlock(&avsync_lock);
     
    163241        return;
    164242    }
    165243    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     244    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    166245   
    167246    need_resampler = false;
    168247    killaudio = false;
     
    172251   
    173252    numlowbuffer = 0;
    174253
     254    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     255            .arg(audio_main_device).arg(audio_channels)
     256            .arg(source_audio_channels).arg(audio_samplerate));
     257   
    175258    // Actually do the device specific open call
    176259    if (!OpenDevice())
    177260    {
    178261        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179262        pthread_mutex_unlock(&avsync_lock);
    180263        pthread_mutex_unlock(&audio_buflock);
     264        if (GetError().isEmpty())
     265            Error("Aborting reconfigure");
     266        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181267        return;
    182268    }
    183269
     
    200286    current_seconds = -1;
    201287    source_bitrate = -1;
    202288
     289    // NOTE: this wont do anything as above samplerate vars are set equal
    203290    // Check if we need the resampler
    204291    if (audio_samplerate != laudio_samplerate)
    205292    {
     
    222309        need_resampler = true;
    223310    }
    224311
     312    if (needs_upmix)
     313    {
     314        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     315        upmixer = new FreeSurround(audio_samplerate, source == AUDIOOUTPUT_VIDEO);
     316        VERBOSE(VB_AUDIO, LOC + QString("create upmixer done"));
     317    }
     318
    225319    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226320            .arg(audio_stretchfactor));
     321    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     322            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    227323
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     324    if (redo_stretch)
    230325    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     326        float laudio_stretchfactor = audio_stretchfactor;
     327        delete pSoundStretch;
     328        pSoundStretch = NULL;
     329        audio_stretchfactor = 0.0;
     330        SetStretchFactorLocked(laudio_stretchfactor);
    233331    }
     332    else
     333    {
     334        SetStretchFactorLocked(audio_stretchfactor);
     335        if (pSoundStretch)
     336        {
     337            // if its passthru then we need to reencode
     338            if (audio_codec)
     339            {
     340                if (!encoder)
     341                {
     342                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     343                    encoder = new AudioOutputDigitalEncoder();
     344                    if (!encoder->Init(audio_codec->codec_id,
     345                                audio_codec->bit_rate,
     346                                audio_codec->sample_rate,
     347                                audio_codec->channels
     348                                ))
     349                    {
     350                        // eeks
     351                        delete encoder;
     352                        encoder = NULL;
     353                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     354                    }
     355                }
     356            }
     357            if (encoder)
     358            {
     359                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     360                pSoundStretch->setChannels(audio_codec->channels);
     361            }
     362            else
     363            {
     364                pSoundStretch->setSampleRate(audio_samplerate);
     365                pSoundStretch->setChannels(audio_channels);
     366            }
     367        }
     368    }
    234369
    235370    // Setup visualisations, zero the visualisations buffers
    236371    prepareVisuals();
     
    290425        pSoundStretch = NULL;
    291426    }
    292427
     428    if (encoder)
     429    {
     430        delete encoder;
     431        encoder = NULL;
     432    }
     433
     434    if (upmixer)
     435    {
     436        delete upmixer;
     437        upmixer = NULL;
     438    }
     439    needs_upmix = false;
     440
    293441    CloseDevice();
    294442
    295443    killAudioLock.unlock();
     
    303451
    304452void AudioOutputBase::Pause(bool paused)
    305453{
     454    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    306455    pauseaudio = paused;
    307456    audio_actually_paused = false;
    308457}
     
    385534       The reason is that computing 'audiotime' requires acquiring the audio
    386535       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387536       from the audio thread, and then call this from the video thread. */
    388     int ret;
     537    long long ret;
    389538    struct timeval now;
    390539
    391540    if (audiotime == 0)
     
    397546
    398547    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399548    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     549    ret = (long long)(ret * audio_stretchfactor);
    401550
     551#if 1
     552    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     553            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     554            .arg(now.tv_sec).arg(now.tv_usec)
     555            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     556            .arg(ret)
     557            .arg(audiotime)
     558            .arg(audio_stretchfactor)
     559           );
     560#endif
     561
    402562    ret += audiotime;
    403563
    404564    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     565    return (int)ret;
    406566}
    407567
    408568void AudioOutputBase::SetAudiotime(void)
     
    439599    // include algorithmic latencies
    440600    if (pSoundStretch)
    441601    {
     602        // add the effect of any unused but processed samples, AC3 reencode does this
     603        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    442604        // add the effect of unprocessed samples in time stretch algo
    443605        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444606                              audio_bytes_per_sample) / audio_stretchfactor);
    445607    }
    446                
     608
     609    if (upmixer && needs_upmix)
     610    {
     611        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     612    }
     613
    447614    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448615                                   (audio_bytes_per_sample * effdspstretched));
    449616 
    450617    gettimeofday(&audiotime_updated, NULL);
     618#if 1
     619    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     620            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     621            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     622            .arg(audiotime)
     623            .arg(audbuf_timecode)
     624            .arg(totalbuffer)
     625            .arg(soundcard_buffer)
     626            .arg(effdspstretched)
     627            .arg(audio_bytes_per_sample)
     628            .arg(audio_stretchfactor)
     629           );
     630#endif
    451631
    452632    pthread_mutex_unlock(&avsync_lock);
    453633    pthread_mutex_unlock(&audio_buflock);
     
    515695    // NOTE: This function is not threadsafe
    516696
    517697    int afree = audiofree(true);
    518     int len = samples * audio_bytes_per_sample;
     698    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    519699
    520700    // Check we have enough space to write the data
    521701    if (need_resampler && src_ctx)
     
    527707                "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
    528708                .arg(len).arg(AUDBUFSIZE-afree).arg(afree)
    529709                .arg(timecode));
    530 
    531710        return false; // would overflow
    532711    }
    533712
     
    564743
    565744int AudioOutputBase::WaitForFreeSpace(int samples)
    566745{
    567     int len = samples * audio_bytes_per_sample;
     746    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     747    int len = samples * abps;
    568748    int afree = audiofree(false);
    569749
    570750    while (len > afree)
    571751    {
    572752        if (blocking)
    573753        {
    574             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     754            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    575755                    QString("(need %1, available %2)").arg(len).arg(afree));
    576756
    577757            // wait for more space
     
    580760        }
    581761        else
    582762        {
    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;
     763            VERBOSE(VB_IMPORTANT, LOC_ERR +
     764                    QString("Audio buffer overflow, %1 audio samples lost!")
     765                        .arg(samples-afree / abps));
     766            samples = afree / abps;
     767            len = samples * abps;
    587768            if (src_ctx)
    588769            {
    589770                int error = src_reset(src_ctx);
     
    608789   
    609790    int afree = audiofree(false);
    610791
    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));
     792    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     793    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     794            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6 upmixer %7")
     795            .arg(samples)
     796            .arg(samples * abps)
     797            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     798            .arg(needs_upmix).arg((uint)(void*)upmixer)
     799            );
    615800   
    616     len = WaitForFreeSpace(samples);
    617 
    618     if (interleaved)
     801    if (upmixer && needs_upmix)
    619802    {
    620         char *mybuf = (char*)buffer;
    621         int bdiff = AUDBUFSIZE - org_waud;
    622         if (bdiff < len)
     803        int out_samples = 0;
     804        int step = (interleaved)?source_audio_channels:1;
     805        len = WaitForFreeSpace(samples);    // test
     806        for(int itemp=0; itemp<samples; )
    623807        {
    624             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    625             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     808            if (audio_bytes == 2)
     809                itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     810            else
     811                itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     812
     813            int copy_samples = upmixer->numSamples();
     814            if (copy_samples)
     815            {
     816                int copy_len = copy_samples * abps;
     817                out_samples += copy_samples;
     818                if (out_samples > samples)
     819                    len = WaitForFreeSpace(out_samples);
     820                int bdiff = AUDBUFSIZE - org_waud;
     821                if (bdiff < copy_len)
     822                {
     823                    int bdiff_samples = bdiff/abps;
     824                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples);
     825                    upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples));
     826                }
     827                else
     828                {
     829                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples);
     830                }
     831                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     832            }
    626833        }
    627         else
    628             memcpy(audiobuffer + org_waud, mybuf, len);
    629  
    630         org_waud = (org_waud + len) % AUDBUFSIZE;
    631     }
    632     else
     834        if (samples > 0)
     835        {
     836            len = WaitForFreeSpace(out_samples);
     837        }
     838        samples = out_samples;
     839    }
     840    else
    633841    {
    634         char **mybuf = (char**)buffer;
    635         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     842        len = WaitForFreeSpace(samples);
     843
     844        if (interleaved)
    636845        {
    637             for (int chan = 0; chan < audio_channels; chan++)
     846            char *mybuf = (char*)buffer;
     847            int bdiff = AUDBUFSIZE - org_waud;
     848            if (bdiff < len)
    638849            {
    639                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    640                 if (audio_bits == 16)
    641                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     850                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     851                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     852            }
     853            else
     854                memcpy(audiobuffer + org_waud, mybuf, len);
     855     
     856            org_waud = (org_waud + len) % AUDBUFSIZE;
     857        }
     858        else
     859        {
     860            char **mybuf = (char**)buffer;
     861            for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     862            {
     863                for (int chan = 0; chan < audio_channels; chan++)
     864                {
     865                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     866                    if (audio_bits == 16)
     867                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    642868
    643                 if (org_waud >= AUDBUFSIZE)
    644                     org_waud -= AUDBUFSIZE;
     869                    if (org_waud >= AUDBUFSIZE)
     870                        org_waud -= AUDBUFSIZE;
     871                }
    645872            }
    646873        }
    647874    }
    648875
     876    if (samples > 0)
     877    {
    649878    if (pSoundStretch)
    650879    {
     880
    651881        // does not change the timecode, only the number of samples
    652882        // back to orig pos
    653883        org_waud = waud;
    654884        int bdiff = AUDBUFSIZE - org_waud;
    655         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
     885        int nSamplesToEnd = bdiff/abps;
    656886        if (bdiff < len)
    657887        {
    658888            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    659889                                      org_waud), nSamplesToEnd);
    660890            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    661                                       (len - bdiff) / audio_bytes_per_sample);
     891                                      (len - bdiff) / abps);
    662892        }
    663893        else
    664894        {
    665895            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    666                                       org_waud), len / audio_bytes_per_sample);
     896                                      org_waud), len / abps);
    667897        }
    668898
    669         int newLen = 0;
    670         int nSamples;
    671         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    672                                audio_bytes_per_sample);
    673         do
     899        if (encoder)
    674900        {
    675             int samplesToGet = len/audio_bytes_per_sample;
    676             if (samplesToGet > nSamplesToEnd)
     901            // pull out a packet's worth and reencode it until we dont have enough
     902            // for any more packets
     903            soundtouch::SAMPLETYPE* temp_buff =
     904                (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     905            size_t frameSize = encoder->FrameSize()/abps;
     906            VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     907                    QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     908                    .arg(frameSize)
     909                    .arg(encoder->FrameSize())
     910                    .arg(pSoundStretch->numSamples())
     911                   );
     912            // process the same number of samples as it creates a full encoded buffer
     913            // just like before
     914            while (pSoundStretch->numSamples() >= frameSize)
    677915            {
    678                 samplesToGet = nSamplesToEnd;   
     916                int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     917                int amount = encoder->Encode(temp_buff);
     918                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     919                        QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     920                        .arg(amount)
     921                        .arg(got)
     922                        .arg(pSoundStretch->numSamples())
     923                       );
     924                if (amount == 0)
     925                    continue;
     926                //len = WaitForFreeSpace(amount);
     927                char * ob = encoder->GetOutBuff();
     928                if (amount >= bdiff)
     929                {
     930                    memcpy(audiobuffer + org_waud, ob, bdiff);
     931                    ob += bdiff;
     932                    amount -= bdiff;
     933                    org_waud = 0;
     934                }
     935                if (amount > 0)
     936                    memcpy(audiobuffer + org_waud, ob, amount);
     937                bdiff = AUDBUFSIZE - amount;
     938                org_waud += amount;
    679939            }
    680 
    681             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    682                                       (audiobuffer + org_waud), samplesToGet);
    683             if (nSamples == nSamplesToEnd)
     940        }
     941        else
     942        {
     943            int newLen = 0;
     944            int nSamples;
     945            len = WaitForFreeSpace(pSoundStretch->numSamples() *
     946                                   audio_bytes_per_sample);
     947            do
    684948            {
    685                 org_waud = 0;
    686                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
    687             }
    688             else
    689             {
    690                 org_waud += nSamples * audio_bytes_per_sample;
    691                 nSamplesToEnd -= nSamples;
    692             }
     949                int samplesToGet = len/audio_bytes_per_sample;
     950                if (samplesToGet > nSamplesToEnd)
     951                {
     952                    samplesToGet = nSamplesToEnd;   
     953                }
    693954
    694             newLen += nSamples * audio_bytes_per_sample;
    695             len -= nSamples * audio_bytes_per_sample;
    696         } while (nSamples > 0);
     955                nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     956                                          (audiobuffer + org_waud), samplesToGet);
     957                if (nSamples == nSamplesToEnd)
     958                {
     959                    org_waud = 0;
     960                    nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     961                }
     962                else
     963                {
     964                    org_waud += nSamples * audio_bytes_per_sample;
     965                    nSamplesToEnd -= nSamples;
     966                }
     967
     968                newLen += nSamples * audio_bytes_per_sample;
     969                len -= nSamples * audio_bytes_per_sample;
     970            } while (nSamples > 0);
     971        }
    697972    }
    698973
    699974    waud = org_waud;
     
    715990
    716991    if (interleaved)
    717992        dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
     993    }
    718994
    719995    pthread_mutex_unlock(&audio_buflock);
    720996}
     
    7691045            space_on_soundcard = getSpaceOnSoundcard();
    7701046
    7711047            if (space_on_soundcard != last_space_on_soundcard) {
    772                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1048                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7731049                        .arg(space_on_soundcard));
    7741050                last_space_on_soundcard = space_on_soundcard;
    7751051            }
     
    7821058                    WriteAudio(zeros, fragment_size);
    7831059                } else {
    7841060                    // this should never happen now -dag
    785                     VERBOSE(VB_AUDIO, LOC +
     1061                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    7861062                            QString("waiting for space on soundcard "
    7871063                                    "to write zeros: have %1 need %2")
    7881064                            .arg(space_on_soundcard).arg(fragment_size));
     
    8181094        if (fragment_size > audiolen(true))
    8191095        {
    8201096            if (audiolen(true) > 0)  // only log if we're sending some audio
    821                 VERBOSE(VB_AUDIO, LOC +
     1097                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8221098                        QString("audio waiting for buffer to fill: "
    8231099                                "have %1 want %2")
    8241100                        .arg(audiolen(true)).arg(fragment_size));
    8251101
    826             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1102            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8271103            pthread_mutex_lock(&audio_buflock);
    8281104            pthread_cond_broadcast(&audio_bufsig);
    8291105            pthread_mutex_unlock(&audio_buflock);
     
    8371113        if (fragment_size > space_on_soundcard)
    8381114        {
    8391115            if (space_on_soundcard != last_space_on_soundcard) {
    840                 VERBOSE(VB_AUDIO, LOC +
     1116                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8411117                        QString("audio waiting for space on soundcard: "
    8421118                                "have %1 need %2")
    8431119                        .arg(space_on_soundcard).arg(fragment_size));
     
    8991175
    9001176        /* update raud */
    9011177        raud = (raud + fragment_size) % AUDBUFSIZE;
    902         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1178        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9031179        pthread_cond_broadcast(&audio_bufsig);
    9041180
    9051181        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:analog", "ALSA:analog");
     61    gc->addSelection("ALSA:digital", "ALSA:digital");
     62    gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog");
     63    gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
    6064#endif
    6165#ifdef USING_ARTS
    6266    gc->addSelection("ARTS:", "ARTS:");
     
    7882    return gc;
    7983}
    8084
     85static HostComboBox *MaxAudioChannels()
     86{
     87    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     88    gc->setLabel(QObject::tr("Max Audio Channels"));
     89    //gc->addSelection(QObject::tr("Mono"), "1");
     90    //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default
     91    //gc->addSelection(QObject::tr("3 Channel: L C R"), "3");
     92    //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4");
     93    //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5");
     94    //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6");
     95    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     96    gc->addSelection(QObject::tr("6 Channel"), "6");
     97    gc->setHelpText(
     98            QObject::tr("Set the maximum number of audio channels to be decoded. "
     99                "This is for multi-channel/surround audio playback."));
     100    return gc;
     101}
     102
    81103static HostComboBox *PassThroughOutputDevice()
    82104{
    83105    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    31433165             new VerticalConfigurationGroup(false, false, true, true);
    31443166         vgrp0->addChild(AC3PassThrough());
    31453167         vgrp0->addChild(DTSPassThrough());
     3168         addChild(MaxAudioChannels());
    31463169
    31473170         VerticalConfigurationGroup *vgrp1 =
    31483171             new VerticalConfigurationGroup(false, false, true, true);
  • 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);
     
    36503657    audio_passthru = passthru;
    36513658}
    36523659
     3660void NuppelVideoPlayer::SetAudioCodec(void* ac)
     3661{
     3662    audio_codec = ac;
     3663}
     3664
    36533665void NuppelVideoPlayer::SetEffDsp(int dsprate)
    36543666{
    36553667    if (audioOutput)
  • libs/libavcodec/liba52.c

     
    134134    }
    135135}
    136136
     137static inline int16_t convert(int32_t i)
     138{
     139    return av_clip_int16(i - 0x43c00000);
     140}
     141
     142void float2s16_2 (float * _f, int16_t * s16)
     143{
     144    int i;
     145    int32_t * f = (int32_t *) _f;
     146
     147    for (i = 0; i < 256; i++) {
     148        s16[2*i] = convert (f[i]);
     149        s16[2*i+1] = convert (f[i+256]);
     150    }
     151}
     152
     153void float2s16_4 (float * _f, int16_t * s16)
     154{
     155    int i;
     156    int32_t * f = (int32_t *) _f;
     157
     158    for (i = 0; i < 256; i++) {
     159        s16[4*i] = convert (f[i]);
     160        s16[4*i+1] = convert (f[i+256]);
     161        s16[4*i+2] = convert (f[i+512]);
     162        s16[4*i+3] = convert (f[i+768]);
     163    }
     164}
     165
     166void float2s16_5 (float * _f, int16_t * s16)
     167{
     168    int i;
     169    int32_t * f = (int32_t *) _f;
     170
     171    for (i = 0; i < 256; i++) {
     172        s16[5*i] = convert (f[i]);
     173        s16[5*i+1] = convert (f[i+256]);
     174        s16[5*i+2] = convert (f[i+512]);
     175        s16[5*i+3] = convert (f[i+768]);
     176        s16[5*i+4] = convert (f[i+1024]);
     177    }
     178}
     179
     180#define LIKEAC3DEC 1
     181int channels_multi (int flags)
     182{
     183    if (flags & A52_LFE)
     184        return 6;
     185    else if (flags & 1) /* center channel */
     186        return 5;
     187    else if ((flags & A52_CHANNEL_MASK) == A52_2F2R)
     188        return 4;
     189    else
     190        return 2;
     191}
     192
     193void float2s16_multi (float * _f, int16_t * s16, int flags)
     194{
     195    int i;
     196    int32_t * f = (int32_t *) _f;
     197
     198    switch (flags) {
     199    case A52_MONO:
     200        for (i = 0; i < 256; i++) {
     201            s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
     202            s16[5*i+4] = convert (f[i]);
     203        }
     204        break;
     205    case A52_CHANNEL:
     206    case A52_STEREO:
     207    case A52_DOLBY:
     208        float2s16_2 (_f, s16);
     209        break;
     210    case A52_3F:
     211        for (i = 0; i < 256; i++) {
     212            s16[5*i] = convert (f[i]);
     213            s16[5*i+1] = convert (f[i+512]);
     214            s16[5*i+2] = s16[5*i+3] = 0;
     215            s16[5*i+4] = convert (f[i+256]);
     216        }
     217        break;
     218    case A52_2F2R:
     219        float2s16_4 (_f, s16);
     220        break;
     221    case A52_3F2R:
     222        float2s16_5 (_f, s16);
     223        break;
     224    case A52_MONO | A52_LFE:
     225        for (i = 0; i < 256; i++) {
     226#if LIKEAC3DEC
     227            s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     228            s16[6*i+1] = convert (f[i+256]);
     229            s16[6*i+5] = convert (f[i]);
     230#else
     231            s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
     232            s16[6*i+4] = convert (f[i+256]);
     233            s16[6*i+5] = convert (f[i]);
     234#endif
     235        }
     236        break;
     237    case A52_CHANNEL | A52_LFE:
     238    case A52_STEREO | A52_LFE:
     239    case A52_DOLBY | A52_LFE:
     240        for (i = 0; i < 256; i++) {
     241#if LIKEAC3DEC
     242            s16[6*i] = convert (f[i+256]);
     243            s16[6*i+2] = convert (f[i+512]);
     244            s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0;
     245            s16[6*i+5] = convert (f[i]);
     246#else
     247            s16[6*i] = convert (f[i+256]);
     248            s16[6*i+1] = convert (f[i+512]);
     249            s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     250            s16[6*i+5] = convert (f[i]);
     251#endif
     252        }
     253        break;
     254    case A52_3F | A52_LFE:
     255        for (i = 0; i < 256; i++) {
     256#if LIKEAC3DEC
     257            s16[6*i] = convert (f[i+256]);
     258            s16[6*i+2] = convert (f[i+768]);
     259            s16[6*i+3] = s16[6*i+4] = 0;
     260            s16[6*i+1] = convert (f[i+512]);
     261            s16[6*i+5] = convert (f[i]);
     262#else
     263            s16[6*i] = convert (f[i+256]);
     264            s16[6*i+1] = convert (f[i+768]);
     265            s16[6*i+2] = s16[6*i+3] = 0;
     266            s16[6*i+4] = convert (f[i+512]);
     267            s16[6*i+5] = convert (f[i]);
     268#endif
     269        }
     270        break;
     271    case A52_2F2R | A52_LFE:
     272        for (i = 0; i < 256; i++) {
     273#if LIKEAC3DEC
     274            s16[6*i] = convert (f[i+256]);
     275            s16[6*i+1] = 0;
     276            s16[6*i+2] = convert (f[i+512]);
     277            s16[6*i+3] = convert (f[i+768]);
     278            s16[6*i+4] = convert (f[i+1024]);
     279            s16[6*i+5] = convert (f[i]);
     280#else
     281            s16[6*i] = convert (f[i+256]);
     282            s16[6*i+1] = convert (f[i+512]);
     283            s16[6*i+2] = convert (f[i+768]);
     284            s16[6*i+3] = convert (f[i+1024]);
     285            s16[6*i+4] = 0;
     286            s16[6*i+5] = convert (f[i]);
     287#endif
     288        }
     289        break;
     290    case A52_3F2R | A52_LFE:
     291        for (i = 0; i < 256; i++) {
     292#if LIKEAC3DEC
     293            s16[6*i] = convert (f[i+256]);
     294            s16[6*i+1] = convert (f[i+512]);
     295            s16[6*i+2] = convert (f[i+768]);
     296            s16[6*i+3] = convert (f[i+1024]);
     297            s16[6*i+4] = convert (f[i+1280]);
     298            s16[6*i+5] = convert (f[i]);
     299#else
     300            s16[6*i] = convert (f[i+256]);
     301            s16[6*i+1] = convert (f[i+768]);
     302            s16[6*i+2] = convert (f[i+1024]);
     303            s16[6*i+3] = convert (f[i+1280]);
     304            s16[6*i+4] = convert (f[i+512]);
     305            s16[6*i+5] = convert (f[i]);
     306#endif
     307        }
     308        break;
     309    }
     310}
     311
    137312/**** end */
    138313
    139314#define HEADER_SIZE 7
     
    177352                    /* update codec info */
    178353                    avctx->sample_rate = sample_rate;
    179354                    s->channels = ac3_channels[s->flags & 7];
     355                    if (avctx->cqp >= 0)
     356                        avctx->channels = avctx->cqp;
    180357                    if (s->flags & A52_LFE)
    181358                        s->channels++;
    182359                    if (avctx->channels == 0)
     
    199376            s->inbuf_ptr += len;
    200377            buf_size -= len;
    201378        } else {
     379            int chans;
    202380            flags = s->flags;
    203381            if (avctx->channels == 1)
    204382                flags = A52_MONO;
    205             else if (avctx->channels == 2)
    206                 flags = A52_STEREO;
     383            else if (avctx->channels == 2) {
     384                if (s->channels>2)
     385                    flags = A52_DOLBY;
     386                else
     387                    flags = A52_STEREO;
     388            }
    207389            else
    208390                flags |= A52_ADJUST_LEVEL;
    209391            level = 1;
     392            chans = channels_multi(flags);
    210393            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    211394            fail:
    212395                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    217400            for (i = 0; i < 6; i++) {
    218401                if (s->a52_block(s->state))
    219402                    goto fail;
    220                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     403                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    221404            }
    222405            s->inbuf_ptr = s->inbuf;
    223406            s->frame_size = 0;
  • libs/libavcodec/ac3_parser.c

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