Ticket #1104: mythtv_ac3.37.patch

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

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

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

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

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

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

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

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

     
    2525HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h
    2626HEADERS += mythhdd.h mythcdrom.h
    2727HEADERS += compat.h
     28HEADERS += audiooutputdigitalencoder.h
    2829
    2930SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
    3031SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
     
    4041SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp
    4142SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp
    4243SOURCES += mythhdd.cpp mythcdrom.cpp
     44SOURCES += audiooutputdigitalencoder.cpp
    4345
    4446INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./
     47INCLUDEPATH += ../libavutil
     48INCLUDEPATH += ../libmythfreesurround
    4549DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
    4650DEPENDPATH += ../libmythupnp
     51DEPENDPATH += ../libavutil ../libavcodec
     52DEPENDPATH += ../libmythfreesurround
    4753
    4854LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4955LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     56LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION}
     57LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION}
     58LIBS += -lfftw3f
    5059
    5160TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
    5261TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT}
     62TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT}
    5363
    5464inc.path = $${PREFIX}/include/mythtv/
    5565inc.files  = dialogbox.h lcddevice.h mythcontext.h mythdbcon.h
     
    207217use_hidesyms {
    208218    QMAKE_CXXFLAGS += -fvisibility=hidden
    209219}
     220
     221contains( CONFIG_LIBA52, yes ) {
     222    LIBS += -la52
     223}
  • libs/libmyth/audiooutput.h

     
    3131    virtual ~AudioOutput() { };
    3232
    3333    // reconfigure sound out for new params
    34     virtual void Reconfigure(int audio_bits, int audio_channels,
    35                              int audio_samplerate, bool audio_passthru) = 0;
     34    virtual void Reconfigure(int audio_bits,
     35                             int audio_channels,
     36                             int audio_samplerate,
     37                             bool audio_passthru,
     38                             void* audio_codec = NULL
     39                             ) = 0;
    3640   
    3741    virtual void SetStretchFactor(float factor);
    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
     20#define UPMIXINLOOP 0
     21
     22namespace soundtouch {
     23class SoundTouch;
     24};
     25class FreeSurround;
     26class AudioOutputDigitalEncoder;
     27struct AVCodecContext;
     28
    2229#define AUDIO_SRC_IN_SIZE   16384
    2330#define AUDIO_SRC_OUT_SIZE (16384*6)
    2431#define AUDIO_TMP_BUF_SIZE (16384*6)
    2532
     33//#define AUDBUFSIZE 768000
     34//divisible by 12,10,8,6,4,2 and around 1024000
     35//#define AUDBUFSIZE 1024080
     36#define AUDBUFSIZE 1536000
     37
    2638class AudioOutputBase : public AudioOutput
    2739{
    2840 public:
     
    3547    virtual ~AudioOutputBase();
    3648
    3749    // reconfigure sound out for new params
    38     virtual void Reconfigure(int audio_bits, int audio_channels,
    39                              int audio_samplerate, bool audio_passthru);
     50    virtual void Reconfigure(int audio_bits,
     51                             int audio_channels,
     52                             int audio_samplerate,
     53                             bool audio_passthru,
     54                             void* audio_codec = NULL);
    4055   
    4156    // do AddSamples calls block?
    4257    virtual void SetBlocking(bool blocking);
     
    94109    void OutputAudioLoop(void);
    95110    static void *kickoffOutputAudioLoop(void *player);
    96111    void SetAudiotime(void);
    97     int WaitForFreeSpace(int len);
     112    int WaitForFreeSpace(int len, bool wait_min);
    98113
    99114    int audiolen(bool use_lock); // number of valid bytes in audio buffer
    100115    int audiofree(bool use_lock); // number of free bytes in audio buffer
     
    125140    bool audio_passthru;
    126141
    127142    float audio_stretchfactor;
     143    AVCodecContext *audio_codec;
    128144    AudioOutputSource source;
    129145
    130146    bool killaudio;
     
    133149    bool set_initial_vol;
    134150    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    135151   
     152    int configured_audio_channels;
     153
    136154 private:
    137155    // resampler
    138156    bool need_resampler;
     
    144162
    145163    // timestretch
    146164    soundtouch::SoundTouch * pSoundStretch;
     165    AudioOutputDigitalEncoder * encoder;
     166    FreeSurround * upmixer;
    147167
     168#if !UPMIXINLOOP
     169    int source_audio_channels;
     170    int source_audio_bytes_per_sample;
     171#endif
     172    bool needs_upmix;
     173    int surround_mode;
     174
    148175    bool blocking; // do AddSamples calls block?
    149176
    150177    int lastaudiolen;
     
    162189
    163190    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    164191                                    'audiotime' and 'audiotime_updated' */
    165     int audiotime; // timecode of audio leaving the soundcard (same units as
     192    long long audiotime; // timecode of audio leaving the soundcard (same units as
    166193                   //                                          timecodes) ...
    167194    struct timeval audiotime_updated; // ... which was last updated at this time
    168195
    169196    /* Audio circular buffer */
    170197    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    171198    int raud, waud;     /* read and write positions */
    172     int audbuf_timecode;    /* timecode of audio most recently placed into
     199    long long audbuf_timecode;    /* timecode of audio most recently placed into
    173200                   buffer */
    174201
    175202    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#if !UPMIXINLOOP
     58    source_audio_channels(-1),
     59    source_audio_bytes_per_sample(0),
     60#endif
     61    needs_upmix(false),
     62    surround_mode(FreeSurround::SurroundModePassive),
    5163
     64    blocking(false),
     65
    5266    lastaudiolen(0),            samples_buffered(0),
    5367
    5468    audio_thread_exists(false),
     
    7185    memset(tmp_buff,           0, sizeof(short) * AUDIO_TMP_BUF_SIZE);
    7286    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    7387    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
     88    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    7489
    7590    // You need to call Reconfigure from your concrete class.
    7691    // Reconfigure(laudio_bits,       laudio_channels,
     
    111126            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    112127                                        .arg(audio_stretchfactor));
    113128            pSoundStretch = new soundtouch::SoundTouch();
    114             pSoundStretch->setSampleRate(audio_samplerate);
    115             pSoundStretch->setChannels(audio_channels);
     129            if (audio_codec)
     130            {
     131                if (!encoder)
     132                {
     133                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     134                    encoder = new AudioOutputDigitalEncoder();
     135                    if (!encoder->Init(audio_codec->codec_id,
     136                                audio_codec->bit_rate,
     137                                audio_codec->sample_rate,
     138                                audio_codec->channels
     139                                ))
     140                    {
     141                        // eeks
     142                        delete encoder;
     143                        encoder = NULL;
     144                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     145                    }
     146                }
     147            }
     148            if (encoder)
     149            {
     150                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     151                pSoundStretch->setChannels(audio_codec->channels);
     152            }
     153            else
     154            {
     155                pSoundStretch->setSampleRate(audio_samplerate);
     156                pSoundStretch->setChannels(audio_channels);
     157            }
    116158
    117159            pSoundStretch->setTempo(audio_stretchfactor);
    118160            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    135177}
    136178
    137179void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    138                                  int laudio_samplerate, bool laudio_passthru)
     180                                 int laudio_samplerate, bool laudio_passthru,
     181                                 void* laudio_codec)
    139182{
     183    int codec_id = CODEC_ID_NONE;
     184    int lcodec_id = CODEC_ID_NONE;
     185    int lcchannels = 0;
     186    int cchannels = 0;
     187    int lsource_audio_channels = laudio_channels;
     188    bool lneeds_upmix = false;
     189
     190    if (laudio_codec)
     191    {
     192        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     193        laudio_bits = 16;
     194        laudio_channels = 2;
     195        lsource_audio_channels = laudio_channels;
     196        laudio_samplerate = 48000;
     197        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     198    }
     199    if (audio_codec)
     200    {
     201        codec_id = audio_codec->codec_id;
     202        cchannels = ((AVCodecContext*)audio_codec)->channels;
     203    }
     204    if ((configured_audio_channels == 6) &&
     205        !(laudio_codec || audio_codec))
     206    {
     207#if !UPMIXINLOOP
     208        laudio_channels = configured_audio_channels;
     209#endif
     210        lneeds_upmix = true;
     211        VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     212    }
     213    ClearError();
    140214    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     215        laudio_samplerate == audio_samplerate && !need_resampler &&
     216        laudio_passthru == audio_passthru &&
     217        lneeds_upmix == needs_upmix &&
     218        lcodec_id == codec_id && lcchannels == cchannels)
     219    {
     220        VERBOSE(VB_AUDIO,LOC + "no change exiting");
    143221        return;
    144 
     222    }
    145223    KillAudio();
    146224   
    147225    pthread_mutex_lock(&audio_buflock);
     
    151229    waud = raud = 0;
    152230    audio_actually_paused = false;
    153231   
     232    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154233    audio_channels = laudio_channels;
     234#if !UPMIXINLOOP
     235    source_audio_channels = lsource_audio_channels;
     236#endif
    155237    audio_bits = laudio_bits;
    156238    audio_samplerate = laudio_samplerate;
     239    audio_codec = (AVCodecContext*)laudio_codec;
    157240    audio_passthru = laudio_passthru;
     241    needs_upmix = lneeds_upmix;
    158242    if (audio_bits != 8 && audio_bits != 16)
    159243    {
    160244        pthread_mutex_unlock(&avsync_lock);
     
    163247        return;
    164248    }
    165249    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     250#if !UPMIXINLOOP
     251    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
     252#endif
    166253   
    167254    need_resampler = false;
    168255    killaudio = false;
     
    172259   
    173260    numlowbuffer = 0;
    174261
     262#if UPMIXINLOOP
     263    int fake_channels = audio_channels;
     264    audio_channels = configured_audio_channels;
     265    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     266            .arg(audio_main_device).arg(configured_audio_channels)
     267            .arg(audio_channels).arg(audio_samplerate));
     268   
    175269    // Actually do the device specific open call
     270    bool openresult = OpenDevice();
     271    audio_channels = fake_channels;
     272    if (!openresult)
     273#else
     274    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     275            .arg(audio_main_device).arg(audio_channels)
     276            .arg(source_audio_channels).arg(audio_samplerate));
     277 
     278    // Actually do the device specific open call
    176279    if (!OpenDevice())
     280#endif
    177281    {
    178282        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179283        pthread_mutex_unlock(&avsync_lock);
    180284        pthread_mutex_unlock(&audio_buflock);
     285        if (GetError().isEmpty())
     286            Error("Aborting reconfigure");
     287        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181288        return;
    182289    }
    183290
     
    200307    current_seconds = -1;
    201308    source_bitrate = -1;
    202309
     310    // NOTE: this wont do anything as above samplerate vars are set equal
    203311    // Check if we need the resampler
    204312    if (audio_samplerate != laudio_samplerate)
    205313    {
     
    222330        need_resampler = true;
    223331    }
    224332
     333    if (needs_upmix)
     334    {
     335        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     336        if (configured_audio_channels == 6)
     337        {
     338            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
     339        }
     340        upmixer = new FreeSurround(audio_samplerate,
     341                                    source == AUDIOOUTPUT_VIDEO,
     342                                    (FreeSurround::SurroundMode)surround_mode);
     343        VERBOSE(VB_AUDIO, LOC + QString("create upmixer done with surround mode %1").arg(surround_mode));
     344    }
     345
    225346    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226347            .arg(audio_stretchfactor));
     348    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     349            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    227350
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     351    if (redo_stretch)
    230352    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     353        float laudio_stretchfactor = audio_stretchfactor;
     354        delete pSoundStretch;
     355        pSoundStretch = NULL;
     356        audio_stretchfactor = 0.0;
     357        SetStretchFactorLocked(laudio_stretchfactor);
    233358    }
     359    else
     360    {
     361        SetStretchFactorLocked(audio_stretchfactor);
     362        if (pSoundStretch)
     363        {
     364            // if its passthru then we need to reencode
     365            if (audio_codec)
     366            {
     367                if (!encoder)
     368                {
     369                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     370                    encoder = new AudioOutputDigitalEncoder();
     371                    if (!encoder->Init(audio_codec->codec_id,
     372                                audio_codec->bit_rate,
     373                                audio_codec->sample_rate,
     374                                audio_codec->channels
     375                                ))
     376                    {
     377                        // eeks
     378                        delete encoder;
     379                        encoder = NULL;
     380                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     381                    }
     382                }
     383            }
     384            if (encoder)
     385            {
     386                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     387                pSoundStretch->setChannels(audio_codec->channels);
     388            }
     389            else
     390            {
     391                pSoundStretch->setSampleRate(audio_samplerate);
     392                pSoundStretch->setChannels(audio_channels);
     393            }
     394        }
     395    }
    234396
    235397    // Setup visualisations, zero the visualisations buffers
    236398    prepareVisuals();
     
    290452        pSoundStretch = NULL;
    291453    }
    292454
     455    if (encoder)
     456    {
     457        delete encoder;
     458        encoder = NULL;
     459    }
     460
     461    if (upmixer)
     462    {
     463        delete upmixer;
     464        upmixer = NULL;
     465    }
     466    needs_upmix = false;
     467
    293468    CloseDevice();
    294469
    295470    killAudioLock.unlock();
     
    303478
    304479void AudioOutputBase::Pause(bool paused)
    305480{
     481    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    306482    pauseaudio = paused;
    307483    audio_actually_paused = false;
    308484}
     
    385561       The reason is that computing 'audiotime' requires acquiring the audio
    386562       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387563       from the audio thread, and then call this from the video thread. */
    388     int ret;
     564    long long ret;
    389565    struct timeval now;
    390566
    391567    if (audiotime == 0)
     
    397573
    398574    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399575    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     576    ret = (long long)(ret * audio_stretchfactor);
    401577
     578#if 1
     579    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     580            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     581            .arg(now.tv_sec).arg(now.tv_usec)
     582            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     583            .arg(ret)
     584            .arg(audiotime)
     585            .arg(audio_stretchfactor)
     586           );
     587#endif
     588
    402589    ret += audiotime;
    403590
    404591    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     592    return (int)ret;
    406593}
    407594
    408595void AudioOutputBase::SetAudiotime(void)
     
    439626    // include algorithmic latencies
    440627    if (pSoundStretch)
    441628    {
     629        // add the effect of any unused but processed samples, AC3 reencode does this
     630        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    442631        // add the effect of unprocessed samples in time stretch algo
    443632        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444633                              audio_bytes_per_sample) / audio_stretchfactor);
    445634    }
    446                
     635
     636#if !UPMIXINLOOP
     637    if (upmixer && needs_upmix)
     638    {
     639        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     640    }
     641#endif
     642
    447643    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448644                                   (audio_bytes_per_sample * effdspstretched));
    449645 
    450646    gettimeofday(&audiotime_updated, NULL);
     647#if 1
     648    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     649            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     650            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     651            .arg(audiotime)
     652            .arg(audbuf_timecode)
     653            .arg(totalbuffer)
     654            .arg(soundcard_buffer)
     655            .arg(effdspstretched)
     656            .arg(audio_bytes_per_sample)
     657            .arg(audio_stretchfactor)
     658           );
     659#endif
    451660
    452661    pthread_mutex_unlock(&avsync_lock);
    453662    pthread_mutex_unlock(&audio_buflock);
     
    464673    if (need_resampler && src_ctx)
    465674        len = (int)ceilf(float(len) * src_data.src_ratio);
    466675
     676#if !UPMIXINLOOP
     677    // include samples in upmix buffer that may be flushed
     678    if (needs_upmix && upmixer)
     679        len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample;
     680#endif
     681
    467682    if ((len > afree) && !blocking)
    468683    {
    469684        VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString(
     
    515730    // NOTE: This function is not threadsafe
    516731
    517732    int afree = audiofree(true);
    518     int len = samples * audio_bytes_per_sample;
     733    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    519734
    520735    // Check we have enough space to write the data
    521736    if (need_resampler && src_ctx)
    522737        len = (int)ceilf(float(len) * src_data.src_ratio);
    523738
     739#if !UPMIXINLOOP
     740    // include samples in upmix buffer that may be flushed
     741    if (needs_upmix && upmixer)
     742        len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample;
     743#endif
     744 
    524745    if ((len > afree) && !blocking)
    525746    {
    526747        VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString(
    527748                "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
    528749                .arg(len).arg(AUDBUFSIZE-afree).arg(afree)
    529750                .arg(timecode));
    530 
    531751        return false; // would overflow
    532752    }
    533753
     
    562782    return true;
    563783}
    564784
    565 int AudioOutputBase::WaitForFreeSpace(int samples)
     785int AudioOutputBase::WaitForFreeSpace(int samples, bool wait_min)
    566786{
    567     int len = samples * audio_bytes_per_sample;
     787    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     788    int len = samples * abps;
    568789    int afree = audiofree(false);
    569790
    570791    while (len > afree)
    571792    {
    572793        if (blocking)
    573794        {
    574             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     795            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    575796                    QString("(need %1, available %2)").arg(len).arg(afree));
    576797
    577798            // wait for more space
     
    580801        }
    581802        else
    582803        {
    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;
     804            if (wait_min)
     805            {
     806                int time_to_wait = ((len-afree)*1000000)/(audio_samplerate*abps);
     807                pthread_mutex_unlock(&audio_buflock);
     808                usleep(time_to_wait + 5000);    // 5ms extra to allow for output loop
     809                pthread_mutex_lock(&audio_buflock);
     810                afree = audiofree(false);
     811                wait_min = false;               // do it once only
     812                continue;
     813            }
     814            VERBOSE(VB_IMPORTANT, LOC_ERR +
     815                    QString("Audio buffer overflow, %1 audio samples lost!")
     816                        .arg(samples-afree / abps));
     817            samples = afree / abps;
     818            len = samples * abps;
    587819            if (src_ctx)
    588820            {
    589821                int error = src_reset(src_ctx);
     
    608840   
    609841    int afree = audiofree(false);
    610842
    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));
     843    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     844    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     845            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6 upmixer %7")
     846            .arg(samples)
     847            .arg(samples * abps)
     848            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     849            .arg(needs_upmix).arg((uint)(void*)upmixer)
     850            );
    615851   
    616     len = WaitForFreeSpace(samples);
    617 
    618     if (interleaved)
     852#if !UPMIXINLOOP
     853    if (upmixer && needs_upmix)
    619854    {
    620         char *mybuf = (char*)buffer;
    621         int bdiff = AUDBUFSIZE - org_waud;
    622         if (bdiff < len)
     855        int out_samples = 0;
     856        int step = (interleaved)?source_audio_channels:1;
     857        len = WaitForFreeSpace(samples, true);    // test
     858        for(int itemp=0; itemp<samples; )
    623859        {
    624             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    625             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     860            // just in case it does a processing cycle, release the lock
     861            // to allow the output loop to do output
     862            pthread_mutex_unlock(&audio_buflock);
     863            if (audio_bytes == 2)
     864                itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     865            else
     866                itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     867            pthread_mutex_lock(&audio_buflock);
     868
     869            int copy_samples = upmixer->numSamples();
     870            if (copy_samples)
     871            {
     872                int copy_len = copy_samples * abps;
     873                out_samples += copy_samples;
     874                if (out_samples > samples)
     875                    len = WaitForFreeSpace(out_samples, true);
     876                int bdiff = AUDBUFSIZE - org_waud;
     877                if (bdiff < copy_len)
     878                {
     879                    int bdiff_samples = bdiff/abps;
     880                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples);
     881                    upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples));
     882                }
     883                else
     884                {
     885                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples);
     886                }
     887                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     888            }
    626889        }
    627         else
    628             memcpy(audiobuffer + org_waud, mybuf, len);
    629  
    630         org_waud = (org_waud + len) % AUDBUFSIZE;
    631     }
    632     else
     890        if (samples > 0)
     891        {
     892            len = WaitForFreeSpace(out_samples, true);
     893        }
     894        samples = out_samples;
     895    }
     896    else
     897#endif
    633898    {
    634         char **mybuf = (char**)buffer;
    635         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     899        len = WaitForFreeSpace(samples, true);
     900
     901        if (interleaved)
    636902        {
    637             for (int chan = 0; chan < audio_channels; chan++)
     903            char *mybuf = (char*)buffer;
     904            int bdiff = AUDBUFSIZE - org_waud;
     905            if (bdiff < len)
    638906            {
    639                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    640                 if (audio_bits == 16)
    641                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     907                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     908                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     909            }
     910            else
     911                memcpy(audiobuffer + org_waud, mybuf, len);
     912     
     913            org_waud = (org_waud + len) % AUDBUFSIZE;
     914        }
     915        else
     916        {
     917            char **mybuf = (char**)buffer;
     918            for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     919            {
     920                for (int chan = 0; chan < audio_channels; chan++)
     921                {
     922                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     923                    if (audio_bits == 16)
     924                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    642925
    643                 if (org_waud >= AUDBUFSIZE)
    644                     org_waud -= AUDBUFSIZE;
     926                    if (org_waud >= AUDBUFSIZE)
     927                        org_waud -= AUDBUFSIZE;
     928                }
    645929            }
    646930        }
    647931    }
    648932
    649     if (pSoundStretch)
     933#if !UPMIXINLOOP
     934    if (samples > 0)
     935#endif
    650936    {
    651         // does not change the timecode, only the number of samples
    652         // back to orig pos
    653         org_waud = waud;
    654         int bdiff = AUDBUFSIZE - org_waud;
    655         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
    656         if (bdiff < len)
     937        if (pSoundStretch)
    657938        {
    658             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    659                                       org_waud), nSamplesToEnd);
    660             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    661                                       (len - bdiff) / audio_bytes_per_sample);
    662         }
    663         else
    664         {
    665             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    666                                       org_waud), len / audio_bytes_per_sample);
    667         }
    668939
    669         int newLen = 0;
    670         int nSamples;
    671         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    672                                audio_bytes_per_sample);
    673         do
    674         {
    675             int samplesToGet = len/audio_bytes_per_sample;
    676             if (samplesToGet > nSamplesToEnd)
     940            // does not change the timecode, only the number of samples
     941            // back to orig pos
     942            org_waud = waud;
     943            int bdiff = AUDBUFSIZE - org_waud;
     944            int nSamplesToEnd = bdiff/abps;
     945            if (bdiff < len)
    677946            {
    678                 samplesToGet = nSamplesToEnd;   
     947                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     948                                          org_waud), nSamplesToEnd);
     949                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     950                                          (len - bdiff) / abps);
    679951            }
     952            else
     953            {
     954                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     955                                          org_waud), len / abps);
     956            }
    680957
    681             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    682                                       (audiobuffer + org_waud), samplesToGet);
    683             if (nSamples == nSamplesToEnd)
     958            if (encoder)
    684959            {
    685                 org_waud = 0;
    686                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     960                // pull out a packet's worth and reencode it until we dont have enough
     961                // for any more packets
     962                soundtouch::SAMPLETYPE* temp_buff =
     963                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     964                size_t frameSize = encoder->FrameSize()/abps;
     965                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     966                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     967                        .arg(frameSize)
     968                        .arg(encoder->FrameSize())
     969                        .arg(pSoundStretch->numSamples())
     970                       );
     971                // process the same number of samples as it creates a full encoded buffer
     972                // just like before
     973                while (pSoundStretch->numSamples() >= frameSize)
     974                {
     975                    int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     976                    int amount = encoder->Encode(temp_buff);
     977                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     978                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     979                            .arg(amount)
     980                            .arg(got)
     981                            .arg(pSoundStretch->numSamples())
     982                           );
     983                    if (amount == 0)
     984                        continue;
     985                    //len = WaitForFreeSpace(amount);
     986                    char * ob = encoder->GetOutBuff();
     987                    if (amount >= bdiff)
     988                    {
     989                        memcpy(audiobuffer + org_waud, ob, bdiff);
     990                        ob += bdiff;
     991                        amount -= bdiff;
     992                        org_waud = 0;
     993                    }
     994                    if (amount > 0)
     995                        memcpy(audiobuffer + org_waud, ob, amount);
     996                    bdiff = AUDBUFSIZE - amount;
     997                    org_waud += amount;
     998                }
    687999            }
    6881000            else
    6891001            {
    690                 org_waud += nSamples * audio_bytes_per_sample;
    691                 nSamplesToEnd -= nSamples;
     1002                int newLen = 0;
     1003                int nSamples;
     1004                len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1005                                       audio_bytes_per_sample, true);
     1006                do
     1007                {
     1008                    int samplesToGet = len/audio_bytes_per_sample;
     1009                    if (samplesToGet > nSamplesToEnd)
     1010                    {
     1011                        samplesToGet = nSamplesToEnd;   
     1012                    }
     1013
     1014                    nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     1015                                              (audiobuffer + org_waud), samplesToGet);
     1016                    if (nSamples == nSamplesToEnd)
     1017                    {
     1018                        org_waud = 0;
     1019                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1020                    }
     1021                    else
     1022                    {
     1023                        org_waud += nSamples * audio_bytes_per_sample;
     1024                        nSamplesToEnd -= nSamples;
     1025                    }
     1026
     1027                    newLen += nSamples * audio_bytes_per_sample;
     1028                    len -= nSamples * audio_bytes_per_sample;
     1029                } while (nSamples > 0);
    6921030            }
     1031        }
    6931032
    694             newLen += nSamples * audio_bytes_per_sample;
    695             len -= nSamples * audio_bytes_per_sample;
    696         } while (nSamples > 0);
    697     }
     1033        waud = org_waud;
     1034        lastaudiolen = audiolen(false);
    6981035
    699     waud = org_waud;
    700     lastaudiolen = audiolen(false);
     1036        if (timecode < 0)
     1037        {
     1038            // mythmusic doesn't give timestamps..
     1039            timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1040        }
     1041       
     1042        samples_buffered += samples;
     1043       
     1044        /* we want the time at the end -- but the file format stores
     1045           time at the start of the chunk. */
     1046        // even with timestretch, timecode is still calculated from original
     1047        // sample count
     1048        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7011049
    702     samples_buffered += samples;
    703    
    704     if (timecode < 0)
    705     {
    706         // mythmusic doesn't give timestamps..
    707         timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1050        if (interleaved)
     1051#if UPMIXINLOOP
     1052            dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
     1053#else
     1054            dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits);
     1055#endif
    7081056    }
    709    
    710     /* we want the time at the end -- but the file format stores
    711        time at the start of the chunk. */
    712     // even with timestretch, timecode is still calculated from original
    713     // sample count
    714     audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7151057
    716     if (interleaved)
    717         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    718 
    7191058    pthread_mutex_unlock(&audio_buflock);
    7201059}
    7211060
     
    7281067
    7291068    if (source_bitrate == -1)
    7301069    {
     1070#if UPMIXINLOOP
    7311071        source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1072#else
     1073        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
     1074#endif
    7321075    }
    7331076
    7341077    if (ct / 1000 != current_seconds)
    7351078    {
    7361079        current_seconds = ct / 1000;
     1080#if UPMIXINLOOP
    7371081        OutputEvent e(current_seconds, ct,
    7381082                      source_bitrate, audio_samplerate, audio_bits,
    7391083                      audio_channels);
     1084#else
     1085        OutputEvent e(current_seconds, ct,
     1086                      source_bitrate, audio_samplerate, audio_bits,
     1087                      source_audio_channels);
     1088#endif
    7401089        dispatch(e);
    7411090    }
    7421091}
     
    7691118            space_on_soundcard = getSpaceOnSoundcard();
    7701119
    7711120            if (space_on_soundcard != last_space_on_soundcard) {
    772                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1121                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7731122                        .arg(space_on_soundcard));
    7741123                last_space_on_soundcard = space_on_soundcard;
    7751124            }
     
    7821131                    WriteAudio(zeros, fragment_size);
    7831132                } else {
    7841133                    // this should never happen now -dag
    785                     VERBOSE(VB_AUDIO, LOC +
     1134                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    7861135                            QString("waiting for space on soundcard "
    7871136                                    "to write zeros: have %1 need %2")
    7881137                            .arg(space_on_soundcard).arg(fragment_size));
     
    8181167        if (fragment_size > audiolen(true))
    8191168        {
    8201169            if (audiolen(true) > 0)  // only log if we're sending some audio
    821                 VERBOSE(VB_AUDIO, LOC +
     1170                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8221171                        QString("audio waiting for buffer to fill: "
    8231172                                "have %1 want %2")
    8241173                        .arg(audiolen(true)).arg(fragment_size));
    8251174
    826             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1175            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8271176            pthread_mutex_lock(&audio_buflock);
    8281177            pthread_cond_broadcast(&audio_bufsig);
    8291178            pthread_mutex_unlock(&audio_buflock);
     
    8371186        if (fragment_size > space_on_soundcard)
    8381187        {
    8391188            if (space_on_soundcard != last_space_on_soundcard) {
    840                 VERBOSE(VB_AUDIO, LOC +
     1189                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8411190                        QString("audio waiting for space on soundcard: "
    8421191                                "have %1 need %2")
    8431192                        .arg(space_on_soundcard).arg(fragment_size));
     
    8991248
    9001249        /* update raud */
    9011250        raud = (raud + fragment_size) % AUDBUFSIZE;
    902         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1251        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9031252        pthread_cond_broadcast(&audio_bufsig);
    9041253
    9051254        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

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

     
    5757#endif
    5858#ifdef USING_ALSA
    5959    gc->addSelection("ALSA:default", "ALSA:default");
     60    gc->addSelection("ALSA:surround51", "ALSA:surround51");
     61    gc->addSelection("ALSA:analog", "ALSA:analog");
     62    gc->addSelection("ALSA:digital", "ALSA:digital");
     63    gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog");
     64    gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
    6065#endif
    6166#ifdef USING_ARTS
    6267    gc->addSelection("ARTS:", "ARTS:");
     
    7883    return gc;
    7984}
    8085
     86static HostComboBox *MaxAudioChannels()
     87{
     88    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     89    gc->setLabel(QObject::tr("Max Audio Channels"));
     90    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     91    gc->addSelection(QObject::tr("5.1"), "6");
     92    gc->setHelpText(
     93            QObject::tr("Set the maximum number of audio channels to be decoded. "
     94                "This is for multi-channel/surround audio playback."));
     95    return gc;
     96}
     97
     98static HostComboBox *AudioUpmixType()
     99{
     100    HostComboBox *gc = new HostComboBox("AudioUpmixType",false);
     101    gc->setLabel(QObject::tr("Upmix"));
     102    gc->addSelection(QObject::tr("Passive"), "0");
     103    gc->addSelection(QObject::tr("Active Simple"), "1");
     104    gc->addSelection(QObject::tr("Active Linear"), "2", true); // default
     105    gc->setHelpText(
     106            QObject::tr("Set the audio upmix type for 2ch to 6ch conversion. "
     107                "This is for multi-channel/surround audio playback."));
     108    return gc;
     109}
     110
    81111static HostComboBox *PassThroughOutputDevice()
    82112{
    83113    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    31453175         vgrp0->addChild(AC3PassThrough());
    31463176         vgrp0->addChild(DTSPassThrough());
    31473177
     3178         HorizontalConfigurationGroup *agrp =
     3179             new HorizontalConfigurationGroup(false, false, true, true);
     3180         agrp->addChild(MaxAudioChannels());
     3181         agrp->addChild(AudioUpmixType());
     3182         addChild(agrp);
     3183
    31483184         VerticalConfigurationGroup *vgrp1 =
    31493185             new VerticalConfigurationGroup(false, false, true, true);
    31503186         vgrp1->addChild(AggressiveBuffer());
  • programs/mythtranscode/transcode.cpp

     
    5555
    5656    // reconfigure sound out for new params
    5757    virtual void Reconfigure(int audio_bits, int audio_channels,
    58                              int audio_samplerate, bool audio_passthru)
     58                             int audio_samplerate, bool audio_passthru,
     59                             void * = NULL)
    5960    {
     61        ClearError();
    6062        (void)audio_samplerate;
    6163        (void)audio_passthru;
    6264        bits = audio_bits;
    6365        channels = audio_channels;
    6466        bytes_per_sample = bits * channels / 8;
     67        if (channels>2)
     68            Error("Invalid channel count");
    6569    }
    6670
    6771    // dsprate is in 100 * samples/second
  • programs/mythuitest/mythuitest.pro

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

     
    259259    bool              allow_ac3_passthru;
    260260    bool              allow_dts_passthru;
    261261    bool              disable_passthru;
     262    int               max_channels;
    262263
    263264    AudioInfo         audioIn;
    264265    AudioInfo         audioOut;
  • libs/libmythtv/avformatdecoder.cpp

     
    5151
    5252#define MAX_AC3_FRAME_SIZE 6144
    5353
    54 /** Set to zero to allow any number of AC3 channels. */
    55 #define MAX_OUTPUT_CHANNELS 2
    56 
    5754static int cc608_parity(uint8_t byte);
    5855static int cc608_good_parity(const int *parity_table, uint16_t data);
    5956static void cc608_build_parity_table(int *parity_table);
     
    417414
    418415    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    419416    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     417    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    420418
    421419    audioIn.sample_size = -32; // force SetupAudioStream to run once
    422420    itv = GetNVP()->GetInteractiveTV();
     
    15801578                            <<") already open, leaving it alone.");
    15811579                }
    15821580                //assert(enc->codec_id);
     1581                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
    15831582
     1583#if 0
     1584                // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this
    15841585                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15851586                if (enc->codec_id == CODEC_ID_DTS)
    15861587                {
     
    15891590                    // enc->bit_rate = what??;
    15901591                }
    15911592                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1593#endif
    15921594
    15931595                bitrate += enc->bit_rate;
    15941596                break;
     
    32603262                    if (!curstream->codec->channels)
    32613263                    {
    32623264                        QMutexLocker locker(&avcodeclock);
    3263                         curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3265                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     3266                        curstream->codec->channels = audioOut.channels;
    32643267                        ret = avcodec_decode_audio(
    32653268                            curstream->codec, audioSamples,
    32663269                            &data_size, ptr, len);
     
    33213324                        AVCodecContext *ctx = curstream->codec;
    33223325
    33233326                        if ((ctx->channels == 0) ||
    3324                             (ctx->channels > MAX_OUTPUT_CHANNELS))
    3325                             ctx->channels = MAX_OUTPUT_CHANNELS;
     3327                            (ctx->channels > audioOut.channels))
     3328                            ctx->channels = audioOut.channels;
    33263329
    33273330                        ret = avcodec_decode_audio(
    33283331                            ctx, audioSamples, &data_size, ptr, len);
     
    36753678
    36763679void AvFormatDecoder::SetDisablePassThrough(bool disable)
    36773680{
     3681    // can only disable never reenable as once timestretch is on its on for the session
     3682    if (disable_passthru)
     3683        return;
    36783684    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    36793685    {
    36803686        disable_passthru = disable;
     
    37073713    AVCodecContext *codec_ctx = NULL;
    37083714    AudioInfo old_in  = audioIn;
    37093715    AudioInfo old_out = audioOut;
     3716    bool using_passthru = false;
    37103717
    37113718    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    37123719        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    37183725        assert(curstream->codec);
    37193726        codec_ctx = curstream->codec;       
    37203727        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3721                                 !disable_passthru &&
    37223728                                (codec_ctx->codec_id == CODEC_ID_AC3));
    37233729        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3724                                 !disable_passthru &&
    37253730                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3731        using_passthru = do_ac3_passthru || do_dts_passthru;
    37263732        info = AudioInfo(codec_ctx->codec_id,
    37273733                         codec_ctx->sample_rate, codec_ctx->channels,
    3728                          do_ac3_passthru || do_dts_passthru);
     3734                         using_passthru && !disable_passthru);
    37293735    }
    37303736
    37313737    if (info == audioIn)
    37323738        return false; // no change
    37333739
     3740    QString ptmsg = "";
     3741    if (using_passthru)
     3742    {
     3743        ptmsg = QString(" using passthru");
     3744    }
    37343745    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    37353746            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    37363747
    37373748    audioOut = audioIn = info;
    3738     if (audioIn.do_passthru)
     3749    if (using_passthru)
    37393750    {
    37403751        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3741         audioOut.channels    = 2;
    3742         audioOut.sample_rate = 48000;
    3743         audioOut.sample_size = 4;
     3752        AudioInfo digInfo = audioOut;
     3753        if (!disable_passthru)
     3754        {
     3755            digInfo.channels    = 2;
     3756            digInfo.sample_rate = 48000;
     3757            digInfo.sample_size = 4;
     3758        }
     3759        if (audioOut.channels > max_channels)
     3760        {
     3761            audioOut.channels = max_channels;
     3762            audioOut.sample_size = audioOut.channels * 2;
     3763            codec_ctx->channels = audioOut.channels;
     3764        }
     3765        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3766                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3767                .arg(digInfo.toString())
     3768                .arg(old_in.toString()).arg(old_out.toString())
     3769                .arg(audioIn.toString()).arg(audioOut.toString()));
     3770
     3771        if (digInfo.sample_rate > 0)
     3772            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3773
     3774        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3775                                 digInfo.sample_rate, audioIn.do_passthru);
     3776        // allow the audio stuff to reencode
     3777        GetNVP()->SetAudioCodec(codec_ctx);
     3778        GetNVP()->ReinitAudio();
     3779        return true;
    37443780    }
    37453781    else
    37463782    {
    3747         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3783        if (audioOut.channels > max_channels)
    37483784        {
    3749             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3785            audioOut.channels = max_channels;
    37503786            audioOut.sample_size = audioOut.channels * 2;
    3751             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3787            codec_ctx->channels = audioOut.channels;
    37523788        }
    37533789    }
     3790    bool audiook;
    37543791
    37553792    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    37563793            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    37633800    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    37643801                             audioOut.sample_rate,
    37653802                             audioIn.do_passthru);
    3766     GetNVP()->ReinitAudio();
     3803    // allow the audio stuff to reencode
     3804    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3805    QString errMsg = GetNVP()->ReinitAudio();
     3806    audiook = errMsg.isEmpty();
    37673807
    37683808    return true;
    37693809}
  • libs/libmythtv/NuppelVideoPlayer.h

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

     
    206206      audio_passthru_device(QString::null),
    207207      audio_channels(2),            audio_bits(-1),
    208208      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     209      audio_codec(NULL),
    209210      // Picture-in-Picture
    210211      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    211212      // Preview window support
     
    767768    if (audioOutput)
    768769    {
    769770        audioOutput->Reconfigure(audio_bits, audio_channels,
    770                                  audio_samplerate, audio_passthru);
     771                                 audio_samplerate, audio_passthru,
     772                                 audio_codec);
    771773        errMsg = audioOutput->GetError();
    772774        if (!errMsg.isEmpty())
    773775            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    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;