Ticket #1104: mythtv_ac3.35.patch
File mythtv_ac3.35.patch, 105.4 KB (added by , 18 years ago) |
---|
-
libs/libmyth/audiooutputdigitalencoder.cpp
1 // Std C headers 2 #include <cstdio> 3 4 // libav headers 5 extern "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 24 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder() 25 { 26 av_context = NULL; 27 outbuf = NULL; 28 outbuf_size = 0; 29 one_frame_bytes = 0; 30 frame_buffer = NULL; 31 } 32 33 AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder() 34 { 35 Dispose(); 36 } 37 38 void 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 61 bool 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 106 static 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 112 static 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 121 static 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 179 static 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 203 extern "C" int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, 204 int *bit_rate, int *samples); 205 206 static 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 298 size_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 4 extern "C" { 5 #include "libavcodec/avcodec.h" 6 }; 7 8 class AudioOutputDigitalEncoder 9 { 10 public: 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; 30 private: 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 /* 2 Copyright (C) 2007 Christian Kothe 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, 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 29 typedef std::complex<float> cfloat; 30 31 const float PI = 3.141592654; 32 const float epsilon = 0.000001; 33 const float center_level = 0.5*sqrt(0.5); // gain of the center channel 34 35 // private implementation of the surround decoder 36 class decoder_impl { 37 public: 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 // append incoming data to the end of the input buffer 106 for (unsigned k=0;k<N;k++) { 107 inbuf[0][k+N/2] = input[0][k]; 108 inbuf[1][k+N/2] = input[1][k]; 109 } 110 // process first part 111 float *in_first[2] = {&inbuf[0][0],&inbuf[1][0]}; 112 add_output(in_first,output,center_width,dimension,adaption_rate); 113 // process second part (overlapped) and return result 114 float *in_second[2] = {&inbuf[0][N/2],&inbuf[1][N/2]}; 115 add_output(in_second,output,center_width,dimension,adaption_rate,true); 116 // shift last third of input buffer to the beginning 117 for (unsigned k=0;k<N/2;k++) { 118 inbuf[0][k] = inbuf[0][k+N]; 119 inbuf[1][k] = inbuf[1][k+N]; 120 } 121 } 122 123 // flush the internal buffers 124 void flush() { 125 for (unsigned k=0;k<N+N/2;k++) { 126 for (unsigned c=0;c<6;c++) 127 outbuf[c][k] = 0; 128 inbuf[0][k] = 0; 129 inbuf[1][k] = 0; 130 } 131 } 132 133 // set the assumed surround mixing coefficients 134 void surround_coefficients(float a, float b) { 135 master_gain = 1.0; 136 // calc the simple coefficients 137 surround_high = a; 138 surround_low = b; 139 surround_balance = (a-b)/(a+b); 140 surround_level = 1/(a+b); 141 // calc the linear coefficients 142 cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0); 143 A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n; 144 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 145 } 146 147 // set the phase shifting mode 148 void phase_mode(unsigned mode) { 149 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; 150 phase_offsetL = modes[mode][0]; 151 phase_offsetR = modes[mode][1]; 152 } 153 154 // what steering mode should be chosen 155 void steering_mode(bool mode) { linear_steering = mode; } 156 157 // set front & rear separation controls 158 void separation(float front, float rear) { 159 front_separation = front; 160 rear_separation = rear; 161 } 162 163 private: 164 // polar <-> cartesian coodinates conversion 165 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); } 166 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); } 167 static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); } 168 static inline float sqr(float x) { return x*x; } 169 // the dreaded min/max 170 static inline float min(float a, float b) { return a<b?a:b; } 171 static inline float max(float a, float b) { return a>b?a:b; } 172 static inline float clamp(float x) { return max(-1,min(1,x)); } 173 174 // handle the output buffering for overlapped calls of block_decode 175 void add_output(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate, bool result=false) { 176 // add the windowed data to the last 2/3 of the output buffer 177 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]}; 178 block_decode(input,out,center_width,dimension,adaption_rate); 179 for (unsigned c=0;c<6;c++) { 180 if (result) 181 // return the first 2/3 of the ouput buffer 182 for (unsigned k=0;k<N;k++) 183 output[c][k] = outbuf[c][k]; 184 for (unsigned k=0;k<N;k++) 185 // shift the last 2/3 to the first 2/3 of the output buffer 186 outbuf[c][k] = outbuf[c][k+N/2]; 187 // and clear the rest 188 for (unsigned k=N;k<N+N/2;k++) 189 outbuf[c][k] = 0; 190 } 191 } 192 193 // CORE FUNCTION: decode a block of data 194 void block_decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 195 // 1. scale the input by the window function; this serves a dual purpose: 196 // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed 197 // - second it allows for smooth blending of varying filters between the blocks 198 for (unsigned k=0;k<N;k++) { 199 lt[k] = input[0][k] * wnd[k] * master_gain; 200 rt[k] = input[1][k] * wnd[k] * master_gain; 201 } 202 203 // ... and tranform it into the frequency domain 204 fftwf_execute(loadL); 205 fftwf_execute(loadR); 206 207 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 208 for (unsigned f=0;f<=N/2;f++) { 209 // get left/right amplitudes/phases 210 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 211 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); 212 // if (ampL+ampR < epsilon) 213 // continue; 214 215 // calculate the amplitude/phase difference 216 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 217 float phaseDiff = phaseL - phaseR; 218 if (phaseDiff < -PI) phaseDiff += 2*PI; 219 if (phaseDiff > PI) phaseDiff -= 2*PI; 220 phaseDiff = abs(phaseDiff); 221 222 if (linear_steering) { 223 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2); 224 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */ 225 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real(); 226 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G); 227 228 /* 229 Problem: 230 This assumes that the values are interpolated linearly between the cardinal points. 231 But this way we have no chance of knowing the average volume... 232 - Can we solve that computing everything under the assumption of normalized volume? 233 No. Seemingly not. 234 - Maybe we should add w explitcitly into the equation and see if we can solve it... 235 */ 236 237 238 //cfloat lt(0.5,0),rt(0.5,0); 239 //cfloat x(0,0), y(1,0); 240 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E); 241 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E); 242 cfloat s = sqrt(p*p/4.0f - q); 243 cfloat x = -p; 244 cfloat x1 = -p/2.0f + s; 245 cfloat x2 = -p/2.0f - s; 246 float x = 0; 247 if (x1.real() >= -1 && x1.real() <= 1) 248 x = x1.real(); 249 else if (x2.real() >= -1 && x2.real() <= 1) 250 x = x2.real();*/ 251 252 //cfloat yp = (rt - (x*E+H))/(F+x*G); 253 //cfloat xp = (lt - (y*B+D))/(A+y*C); 254 255 /*xfs[f] = x; 256 yfs[f] = y.real();*/ 257 258 // --- this is the fancy new linear mode --- 259 260 // get sound field x/y position 261 yfs[f] = get_yfs(ampDiff,phaseDiff); 262 xfs[f] = get_xfs(ampDiff,yfs[f]); 263 264 // add dimension control 265 yfs[f] = clamp(yfs[f] - dimension); 266 267 // add crossfeed control 268 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 269 270 // 3. generate frequency filters for each output channel 271 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 272 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 273 float volume[5] = { 274 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 275 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 276 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 277 back * surround_level * left, // left surround 278 back * surround_level * right // right surround 279 }; 280 281 // adapt the prior filter 282 for (unsigned c=0;c<5;c++) 283 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N; 284 285 } else { 286 // --- this is the old & simple steering mode --- 287 288 // calculate the amplitude/phase difference 289 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 290 float phaseDiff = phaseL - phaseR; 291 if (phaseDiff < -PI) phaseDiff += 2*PI; 292 if (phaseDiff > PI) phaseDiff -= 2*PI; 293 phaseDiff = abs(phaseDiff); 294 295 // determine sound field x-position 296 xfs[f] = ampDiff; 297 298 // determine preliminary sound field y-position from phase difference 299 yfs[f] = 1 - (phaseDiff/PI)*2; 300 301 if (abs(xfs[f]) > surround_balance) { 302 // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance 303 // this is necessary because the sound field is trapezoidal and will be stretched behind the listener 304 float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance); 305 yfs[f] = (1-frontness) * yfs[f] + frontness * 1; 306 } 307 308 // add dimension control 309 yfs[f] = clamp(yfs[f] - dimension); 310 311 // add crossfeed control 312 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 313 314 // 3. generate frequency filters for each output channel, according to the signal position 315 // the sum of all channel volumes must be 1.0 316 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 317 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 318 float volume[5] = { 319 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 320 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 321 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 322 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))), // left surround 323 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2))) // right surround 324 }; 325 326 // adapt the prior filter 327 for (unsigned c=0;c<5;c++) 328 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N; 329 } 330 331 // ... and build the signal which we want to position 332 frontL[f] = polar(ampL+ampR,phaseL); 333 frontR[f] = polar(ampL+ampR,phaseR); 334 avg[f] = frontL[f] + frontR[f]; 335 surL[f] = polar(ampL+ampR,phaseL+phase_offsetL); 336 surR[f] = polar(ampL+ampR,phaseR+phase_offsetR); 337 #ifdef FILTERED_LFE 338 trueavg[f] = cfloat(dftL[f][0] + dftR[f][0], dftL[f][1] + dftR[f][1]); 339 #endif 340 } 341 342 // 4. distribute the unfiltered reference signals over the channels 343 apply_filter(&frontL[0],&filter[0][0],&output[0][0]); // front left 344 apply_filter(&avg[0], &filter[1][0],&output[1][0]); // front center 345 apply_filter(&frontR[0],&filter[2][0],&output[2][0]); // front right 346 apply_filter(&surL[0],&filter[3][0],&output[3][0]); // surround left 347 apply_filter(&surR[0],&filter[4][0],&output[4][0]); // surround right 348 #ifdef FILTERED_LFE 349 apply_filter(&trueavg[0],&filter[5][0],&output[5][0]); // lfe 350 #else 351 double g = master_gain; 352 // introduce a delay of N/2 too to match the other channels 353 for (unsigned k=0,k2=N/2;k<N/2;k++,k2++) { 354 output[5][k] = (input[0][k2] + input[1][k2]) * g; 355 } 356 #endif 357 } 358 359 #define FASTER_CALC 360 // map from amplitude difference and phase difference to yfs 361 inline double get_yfs(double ampDiff, double phaseDiff) { 362 double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2); 363 #ifdef FASTER_CALC 364 double tanX = tan(x); 365 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 366 + 0.09170680403453149*x*x*x + 0.2617754892323973*tanX - 0.04180413533856156*sqr(tanX); 367 #else 368 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 369 + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x)); 370 #endif 371 } 372 373 // map from amplitude difference and yfs to xfs 374 inline double get_xfs(double ampDiff, double yfs) { 375 double x=ampDiff,y=yfs; 376 #ifdef FASTER_CALC 377 double tanX = tan(x); 378 double tanY = tan(y); 379 double asinX = asin(x); 380 double sinX = sin(x); 381 double sinY = sin(y); 382 double x3 = x*x*x; 383 double y2 = y*y; 384 double y3 = y*y2; 385 return 2.464833559224702*x - 423.52131153259404*x*y + 386 67.8557858606918*x3*y + 788.2429425544392*x*y2 - 387 79.97650354902909*x3*y2 - 513.8966153850349*x*y3 + 388 35.68117670186306*x3*y3 + 13867.406173420834*y*asinX - 389 2075.8237075786396*y2*asinX - 908.2722068360281*y3*asinX - 390 12934.654772878019*asinX*sinY - 13216.736529661162*y*tanX + 391 1288.6463247741938*y2*tanX + 1384.372969378453*y3*tanX + 392 12699.231471126128*sinY*tanX + 95.37131275594336*sinX*tanY - 393 91.21223198407546*tanX*tanY; 394 #else 395 return 2.464833559224702*x - 423.52131153259404*x*y + 396 67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y - 397 79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y + 398 35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) - 399 2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) - 400 12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) + 401 1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) + 402 12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) - 403 91.21223198407546*tan(x)*tan(y); 404 #endif 405 } 406 407 // filter the complex source signal and add it to target 408 void apply_filter(cfloat *signal, float *flt, float *target) { 409 // filter the signal 410 for (unsigned f=0;f<=N/2;f++) { 411 src[f][0] = signal[f].real() * flt[f]; 412 src[f][1] = signal[f].imag() * flt[f]; 413 } 414 // transform into time domain 415 fftwf_execute(store); 416 // add the result to target, windowed 417 for (unsigned k=0;k<N;k++) 418 target[k] += wnd[k]*dst[k]; 419 } 420 421 unsigned N; // the block size 422 // FFTW data structures 423 float *lt,*rt,*dst; // left total, right total (source arrays), destination array 424 fftwf_complex *dftL,*dftR,*src; // intermediate arrays (FFTs of lt & rt, processing source) 425 fftwf_plan loadL,loadR,store; // plans for loading the data into the intermediate format and back 426 // buffers 427 std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain 428 #ifdef FILTERED_LFE 429 std::vector<cfloat> trueavg; // for lfe generation 430 #endif 431 std::vector<float> xfs,yfs; // the feature space positions for each frequency bin 432 std::vector<float> wnd; // the window function, precalculated 433 std::vector<float> filter[6]; // a frequency filter for each output channel 434 std::vector<float> inbuf[2]; // the sliding input buffers 435 std::vector<float> outbuf[6]; // the sliding output buffers 436 // coefficients 437 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 438 float surround_balance; // the xfs balance that follows from the coeffs 439 float surround_level; // gain for the surround channels (follows from the coeffs 440 float master_gain; // gain for all channels 441 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 442 float front_separation; // front stereo separation 443 float rear_separation; // rear stereo separation 444 bool linear_steering; // whether the steering should be linear or not 445 cfloat A,B,C,D,E,F,G,H; // coefficients for the linear steering 446 }; 447 448 449 // implementation of the shell class 450 451 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { } 452 453 fsurround_decoder::~fsurround_decoder() { delete impl; } 454 455 void fsurround_decoder::decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 456 impl->decode(input,output,center_width,dimension,adaption_rate); 457 } 458 459 void fsurround_decoder::flush() { impl->flush(); } 460 461 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 462 463 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 464 465 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); } 466 467 void fsurround_decoder::separation(float front, float rear) { impl->separation(front,rear); } -
libs/libmythfreesurround/el_processor.h
1 /* 2 Copyright (C) 2007 Christian Kothe 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19 #ifndef EL_PROCESSOR_H 20 #define EL_PROCESSOR_H 21 22 // the Free Surround decoder 23 class fsurround_decoder { 24 public: 25 // create an instance of the decoder 26 // blocksize is fixed over the lifetime of this object for performance reasons 27 fsurround_decoder(unsigned blocksize=8192); 28 // destructor 29 ~fsurround_decoder(); 30 31 // decode a chunk of stereo sound, has to contain exactly blocksize samples 32 // center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution 33 // dimension [0..1] moves the soundfield backwards, 0=front, 1=side 34 // adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption 35 void decode(float *input[2], float *output[6], float center_width=1, float dimension=0, float adaption_rate=1); 36 37 // flush the internal buffers 38 void flush(); 39 40 // --- advanced configuration --- 41 42 // override the surround coefficients 43 // a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right. 44 void surround_coefficients(float a, float b); 45 46 // set the phase shifting mode for decoding 47 // 0 = (+0°,+0°) - music mode 48 // 1 = (+0°,+180°) - PowerDVD compatibility 49 // 2 = (+180°,+0°) - BeSweet compatibility 50 // 3 = (-90°,+90°) - This seems to work. I just don't know why. 51 void phase_mode(unsigned mode); 52 53 // override the steering mode 54 // false = simple non-linear steering (old) 55 // true = advanced linear steering (new) 56 void steering_mode(bool mode); 57 58 // set front/rear stereo separation 59 // 1.0 is default, 0.0 is mono 60 void separation(float front,float rear); 61 private: 62 class decoder_impl *impl; // private implementation (details hidden) 63 }; 64 65 66 #endif -
libs/libmythfreesurround/freesurround.cpp
1 /* 2 Copyright (C) 2007 Christian Kothe, Mark Spieth 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, 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 35 using 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 63 const unsigned block_size = 8192; 64 // there will be a slider for this in the future 65 const float master_gain = 1.0/(1<<15); 66 const float inv_master_gain = (1<<15); 67 68 unsigned bs = block_size; 69 70 // stupidity countermeasure... 71 template<class T> T pop_back(std::list<T> &l) { T result(l.back()); l.pop_back(); return result; } 72 73 // a pool, where the DSP can throw its objects at after it got deleted and get them back when it is recreated... 74 class object_pool { 75 public: 76 typedef void* (*callback)(); 77 typedef std::map< void* , void* > map_t; 78 typedef map_t::iterator mapiterator; 79 // initialize 80 object_pool(callback cbf):construct(cbf) { } 81 ~object_pool() { 82 for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();i!=e;i++) 83 //for (mapiterator i=pool.begin(),e=pool.end();i!=e;i++) 84 delete i->second; 85 for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();i!=e;i++) 86 delete *i; 87 } 88 // (re)acquire an object 89 void *acquire(void *who) { 90 std::map<void*,void*>::iterator i(pool.find(who)); 91 if (i != pool.end()) 92 return i->second; 93 else 94 if (!freelist.empty()) 95 return pool.insert(std::make_pair(who,pop_back(freelist))).first->second; 96 else 97 return pool.insert(std::make_pair(who,construct())).first->second; 98 } 99 // release an object into the wild 100 void release(void *who) { 101 std::map<void*,void*>::iterator i(pool.find(who)); 102 if (i != pool.end()) { 103 freelist.push_back(i->second); 104 pool.erase(i); 105 } 106 } 107 public: 108 callback construct; // object constructor callback 109 std::list<void*> freelist; // list of available objects 110 std::map<void*,void*> pool; // pool of used objects, by class 111 }; 112 113 // buffers which we usually need (and want to share between plugin lifespans) 114 struct buffers { 115 buffers(unsigned int s): 116 //block(),result(s), 117 lt(s),rt(s), 118 l(s),r(s),c(s),ls(s),rs(s),lfe(s),cs(s),lcs(s),rcs(s) { } 119 void resize(unsigned int s) { 120 lt.resize(s); rt.resize(s); l.resize(s); r.resize(s); lfe.resize(s); 121 ls.resize(s); rs.resize(s); c.resize(s); cs.resize(s); lcs.resize(s); rcs.resize(s); 122 } 123 void clear() { 124 lt.clear(); rt.clear(); l.clear(); r.clear(); 125 ls.clear(); rs.clear(); c.clear(); 126 //block.clear(); result.clear(); 127 } 128 //std::vector<short> block,result; // for buffering 129 std::vector<float> lt,rt; // for multiplexing 130 std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs; // for demultiplexing 131 }; 132 133 // construction methods 134 void *new_decoder() { return new fsurround_decoder(block_size); } 135 void *new_buffers() { return new buffers(bs); } 136 137 object_pool dp(&new_decoder); 138 object_pool bp(&new_buffers); 139 140 //#define SPEAKERTEST 141 #ifdef SPEAKERTEST 142 int channel_select = -1; 143 #endif 144 145 FreeSurround::FreeSurround(uint srate, bool moviemode) : 146 srate(srate), 147 open_(false), 148 initialized_(false), 149 bufs((buffers*)bp.acquire(this)), 150 decoder(0), 151 in_count(0), 152 out_count(0), 153 processed(true) 154 { 155 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 156 if (moviemode) 157 { 158 params.phasemode = 1; 159 params.center_width = 0; 160 //params.steering = 0; 161 } 162 else 163 { 164 params.center_width = 50; 165 } 166 open(); 167 #ifdef SPEAKERTEST 168 channel_select++; 169 if (channel_select>=6) 170 channel_select = 0; 171 VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select)); 172 #endif 173 174 VERBOSE(QString("FreeSurround::FreeSurround done")); 175 } 176 177 FreeSurround::fsurround_params::fsurround_params( 178 int32_t center_width, 179 int32_t dimension 180 ) : 181 center_width(center_width), 182 dimension(dimension), 183 coeff_a(0.8165),coeff_b(0.5774), 184 phasemode(0), 185 steering(1), 186 front_sep(100), 187 rear_sep(100) 188 { 189 } 190 191 FreeSurround::~FreeSurround() 192 { 193 VERBOSE(QString("FreeSurround::~FreeSurround")); 194 close(); 195 bp.release(this); 196 VERBOSE(QString("FreeSurround::~FreeSurround done")); 197 } 198 199 uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step) 200 { 201 int i; 202 int ic = in_count; 203 int bs = block_size; 204 bool process = true; 205 // demultiplex 206 switch (numChannels) 207 { 208 case 1: 209 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 210 { 211 bufs->lt[ic] = 212 bufs->rt[ic] = 213 samples[i]*master_gain; 214 } 215 break; 216 case 2: 217 if (step>0) 218 { 219 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 220 { 221 bufs->lt[ic] = samples[i]*master_gain; 222 bufs->rt[ic] = samples[i+step]*master_gain; 223 } 224 } 225 else 226 { 227 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 228 { 229 bufs->lt[ic] = samples[i*2]*master_gain; 230 bufs->rt[ic] = samples[i*2+1]*master_gain; 231 } 232 } 233 break; 234 case 6: 235 process = false; 236 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 237 { 238 bufs->l[ic] = *samples++ * master_gain; 239 bufs->c[ic] = *samples++ * master_gain; 240 bufs->r[ic] = *samples++ * master_gain; 241 bufs->ls[ic] = *samples++ * master_gain; 242 bufs->rs[ic] = *samples++ * master_gain; 243 bufs->lfe[ic] = *samples++ * master_gain; 244 } 245 break; 246 } 247 in_count = ic; 248 processed = process; 249 if (ic == bs) 250 { 251 in_count = 0; 252 if (process) 253 process_block(); 254 out_count = bs; 255 } 256 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 257 .arg(numSamples) 258 .arg(numChannels) 259 .arg(step) 260 .arg(i) 261 .arg(out_count) 262 ); 263 return i; 264 } 265 266 uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step) 267 { 268 int i; 269 int ic = in_count; 270 int bs = block_size; 271 bool process = true; 272 // demultiplex 273 switch (numChannels) 274 { 275 case 1: 276 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 277 { 278 bufs->lt[ic] = 279 bufs->rt[ic] = 280 samples[i]*master_gain; 281 } 282 break; 283 case 2: 284 if (step>0) 285 { 286 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 287 { 288 bufs->lt[ic] = samples[i]*master_gain; 289 bufs->rt[ic] = samples[i+step]*master_gain; 290 } 291 } 292 else 293 { 294 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 295 { 296 bufs->lt[ic] = samples[i*2]*master_gain; 297 bufs->rt[ic] = samples[i*2+1]*master_gain; 298 } 299 } 300 break; 301 case 6: 302 process = false; 303 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 304 { 305 bufs->l[ic] = *samples++; 306 bufs->c[ic] = *samples++; 307 bufs->r[ic] = *samples++; 308 bufs->ls[ic] = *samples++; 309 bufs->rs[ic] = *samples++; 310 bufs->lfe[ic] = *samples++; 311 } 312 break; 313 } 314 in_count = ic; 315 processed = process; 316 if (ic == bs) 317 { 318 in_count = 0; 319 if (process) 320 process_block(); 321 out_count = bs; 322 } 323 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 324 .arg(numSamples) 325 .arg(numChannels) 326 .arg(step) 327 .arg(i) 328 .arg(out_count) 329 ); 330 return i; 331 } 332 333 uint FreeSurround::receiveSamples( 334 short *output, 335 uint maxSamples 336 ) 337 { 338 uint i; 339 uint oc = out_count; 340 if (maxSamples>oc) maxSamples = oc; 341 uint outindex = block_size - oc; 342 for (unsigned int i=0;i<maxSamples;i++) 343 { 344 #ifndef BYPASS 345 #ifdef SPEAKERTEST 346 *output++ = (channel_select==0)?(short)bufs->l[outindex]:0; //L 347 *output++ = (channel_select==1)?(short)bufs->r[outindex]:0; //R 348 *output++ = (channel_select==2)?(short)bufs->c[outindex]:0; //LS 349 *output++ = (channel_select==3)?(short)bufs->c[outindex]:0; //RS 350 *output++ = (channel_select==4)?(short)bufs->c[outindex]:0; //C 351 *output++ = (channel_select==5)?(short)bufs->c[outindex]:0; //LFE 352 #else 353 *output++ = lrintf(bufs->l[outindex] * inv_master_gain); 354 *output++ = lrintf(bufs->r[outindex] * inv_master_gain); 355 *output++ = lrintf(bufs->ls[outindex] * inv_master_gain); 356 *output++ = lrintf(bufs->rs[outindex] * inv_master_gain); 357 *output++ = lrintf(bufs->c[outindex] * inv_master_gain); 358 *output++ = lrintf(bufs->lfe[outindex] * inv_master_gain); 359 #endif 360 #else 361 *output++ = (short)bufs->lt[outindex]; 362 *output++ = (short)bufs->rt[outindex]; 363 *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7); 364 *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7); 365 *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5); 366 *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5); 367 #endif 368 oc--; 369 outindex++; 370 } 371 out_count = oc; 372 VERBOSE1(QString("FreeSurround::receiveSamples %1") 373 .arg(maxSamples) 374 ); 375 return maxSamples; 376 } 377 378 void FreeSurround::process_block() 379 { 380 #ifndef BYPASS 381 // process the data 382 try { 383 float *input[2] = {&bufs->lt[0], &bufs->rt[0]}; 384 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]}; 385 if (decoder) { 386 // actually these params need only be set when they change... but it doesn't hurt 387 decoder->steering_mode(params.steering); 388 decoder->phase_mode(params.phasemode); 389 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 390 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 391 // decode the bufs->block 392 decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0); 393 } 394 } catch(...) { 395 //throw(std::runtime_error(std::string("error during processing (unsupported input format?)"))); 396 } 397 #endif 398 } 399 400 long long FreeSurround::getLatency() 401 { 402 // returns in usec 403 return decoder ? ((block_size + in_count)*1000000)/(2*srate) : 0; 404 } 405 406 void FreeSurround::flush() { 407 if (decoder) 408 decoder->flush(); 409 bufs->clear(); 410 } 411 412 // load the lib and initialize the interface 413 void FreeSurround::open() 414 { 415 if (!decoder) { 416 decoder = (fsurround_decoder*)dp.acquire(this); 417 decoder->flush(); 418 bufs->clear(); 419 } 420 } 421 422 void FreeSurround::close() 423 { 424 if (decoder) { 425 dp.release(this); 426 decoder = 0; 427 } 428 } 429 430 uint FreeSurround::numUnprocessedSamples() 431 { 432 return in_count; 433 } 434 435 uint FreeSurround::numSamples() 436 { 437 return out_count; 438 } 439 440 uint FreeSurround::sampleLatency() 441 { 442 if (processed) 443 return in_count + out_count + (block_size/2); 444 else 445 return in_count + out_count; 446 } 447 -
libs/libmythfreesurround/freesurround.h
1 /* 2 Copyright (C) 2007 Christian Kothe, Mark Spieth 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19 #ifndef FREESURROUND_H 20 #define FREESURROUND_H 21 22 class FreeSurround 23 { 24 public: 25 FreeSurround(uint srate, bool moviemode); 26 ~FreeSurround(); 27 28 // put samples in buffer, returns number of samples used 29 uint putSamples(short* samples, uint numSamples, uint numChannels, int step); 30 uint putSamples(char* samples, uint numSamples, uint numChannels, int step); 31 // get a number of samples 32 uint receiveSamples(short *output, 33 uint maxSamples 34 ); 35 // flush unprocessed samples 36 void flush(); 37 //void setSampleRate(uint srate); 38 uint numUnprocessedSamples(); 39 uint numSamples(); 40 41 long long getLatency(); 42 uint sampleLatency(); 43 44 protected: 45 void process_block(); 46 void open(); 47 void close(); 48 49 private: 50 51 // the changeable parameters 52 struct fsurround_params { 53 int32_t center_width; // presence of the center channel 54 int32_t dimension; // dimension 55 float coeff_a,coeff_b; // surround mixing coefficients 56 int32_t phasemode; // phase shifting mode 57 int32_t steering; // steering mode (0=simple, 1=linear) 58 int32_t front_sep, rear_sep;// front/rear stereo separation 59 60 // (default) constructor 61 fsurround_params(int32_t center_width=100, int32_t dimension=0); 62 } params; 63 64 // additional settings 65 uint srate; 66 67 // info about the current setup 68 bool open_; // whether a stream is currently open 69 bool initialized_; // whether the thing is intialized 70 struct buffers *bufs; // our buffers 71 class fsurround_decoder *decoder; // the surround decoder 72 int in_count; // amount in lt,rt 73 int out_count; // amount in output bufs 74 bool processed; // whether processing is enabled or not for latency calc 75 76 }; 77 78 #endif 79 -
libs/libmythfreesurround/libmythfreesurround.pro
1 include ( ../../config.mak ) 2 include ( ../../settings.pro ) 3 4 TEMPLATE = lib 5 TARGET = mythfreesurround-$$LIBVERSION 6 CONFIG += thread staticlib warn_off 7 8 INCLUDEPATH += ../../libs/libavcodec ../.. 9 10 #build position independent code since the library is linked into a shared library 11 QMAKE_CXXFLAGS += -fPIC -DPIC 12 13 QMAKE_CLEAN += $(TARGET) $(TARGETA) $(TARGETD) $(TARGET0) $(TARGET1) $(TARGET2) 14 15 # Input 16 HEADERS += el_processor.h 17 HEADERS += freesurround.h 18 19 SOURCES += el_processor.cpp 20 SOURCES += freesurround.cpp 21 22 #required until its rewritten to use avcodec fft lib 23 #LIBS += -lfftw3 24 LIBS += -lfftw3f 25 -
libs/libs.pro
7 7 8 8 # Directories 9 9 SUBDIRS += libavutil libavcodec libavformat libmythsamplerate 10 #SUBDIRS += libaf 10 11 SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav 12 SUBDIRS += libmythfreesurround 11 13 SUBDIRS += libmyth 12 14 13 15 SUBDIRS += libmythupnp libmythui -
libs/libmyth/libmyth.pro
25 25 HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h 26 26 HEADERS += mythhdd.h mythcdrom.h 27 27 HEADERS += compat.h 28 HEADERS += audiooutputdigitalencoder.h 28 29 29 30 SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp 30 31 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp … … 40 41 SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp 41 42 SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp 42 43 SOURCES += mythhdd.cpp mythcdrom.cpp 44 SOURCES += audiooutputdigitalencoder.cpp 43 45 44 46 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./ 47 INCLUDEPATH += ../libavutil 48 INCLUDEPATH += ../libmythfreesurround 45 49 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 46 50 DEPENDPATH += ../libmythupnp 51 DEPENDPATH += ../libavutil ../libavcodec 52 DEPENDPATH += ../libmythfreesurround 47 53 48 54 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 49 55 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 56 LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION} 57 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 58 LIBS += -lfftw3f 50 59 51 60 TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT} 52 61 TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT} 62 TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT} 53 63 54 64 inc.path = $${PREFIX}/include/mythtv/ 55 65 inc.files = dialogbox.h lcddevice.h mythcontext.h mythdbcon.h … … 207 217 use_hidesyms { 208 218 QMAKE_CXXFLAGS += -fvisibility=hidden 209 219 } 220 221 contains( CONFIG_LIBA52, yes ) { 222 LIBS += -la52 223 } -
libs/libmyth/audiooutput.h
31 31 virtual ~AudioOutput() { }; 32 32 33 33 // 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; 36 40 37 41 virtual void SetStretchFactor(float factor); 38 42 … … 74 78 lastError = msg; 75 79 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 76 80 } 81 void ClearError() 82 { lastError = QString::null; }; 77 83 78 84 void Warn(QString msg) 79 85 { -
libs/libmyth/audiooutputdx.h
35 35 /// END HACK HACK HACK HACK 36 36 37 37 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); 40 43 virtual void SetBlocking(bool blocking); 41 44 42 45 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
130 130 // FIXME: kedl: not sure what else could be required here? 131 131 } 132 132 133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 134 int audio_samplerate, int audio_passthru) 133 void AudioOutputDX::Reconfigure(int audio_bits, 134 int audio_channels, 135 int audio_samplerate, 136 int audio_passthru, 137 AudioCodecMode laom 138 ) 135 139 { 136 140 if (dsbuffer) 137 141 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
16 16 // MythTV headers 17 17 #include "audiooutput.h" 18 18 #include "samplerate.h" 19 #include "SoundTouch.h"20 19 21 #define AUDBUFSIZE 768000 20 namespace soundtouch { 21 class SoundTouch; 22 }; 23 class FreeSurround; 24 class AudioOutputDigitalEncoder; 25 struct AVCodecContext; 26 22 27 #define AUDIO_SRC_IN_SIZE 16384 23 28 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 29 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 30 31 //#define AUDBUFSIZE 768000 32 //divisible by 12,10,8,6,4,2 and around 1024000 33 //#define AUDBUFSIZE 1024080 34 #define AUDBUFSIZE 1536000 35 26 36 class AudioOutputBase : public AudioOutput 27 37 { 28 38 public: … … 35 45 virtual ~AudioOutputBase(); 36 46 37 47 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, 50 int audio_samplerate, 51 bool audio_passthru, 52 void* audio_codec = NULL); 40 53 41 54 // do AddSamples calls block? 42 55 virtual void SetBlocking(bool blocking); … … 125 138 bool audio_passthru; 126 139 127 140 float audio_stretchfactor; 141 AVCodecContext *audio_codec; 128 142 AudioOutputSource source; 129 143 130 144 bool killaudio; … … 133 147 bool set_initial_vol; 134 148 bool buffer_output_data_for_use; // used by AudioOutputNULL 135 149 150 int configured_audio_channels; 151 136 152 private: 137 153 // resampler 138 154 bool need_resampler; … … 144 160 145 161 // timestretch 146 162 soundtouch::SoundTouch * pSoundStretch; 163 AudioOutputDigitalEncoder * encoder; 164 FreeSurround * upmixer; 147 165 166 int source_audio_channels; 167 int source_audio_bytes_per_sample; 168 bool needs_upmix; 169 148 170 bool blocking; // do AddSamples calls block? 149 171 150 172 int lastaudiolen; … … 162 184 163 185 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 164 186 'audiotime' and 'audiotime_updated' */ 165 intaudiotime; // timecode of audio leaving the soundcard (same units as187 long long audiotime; // timecode of audio leaving the soundcard (same units as 166 188 // timecodes) ... 167 189 struct timeval audiotime_updated; // ... which was last updated at this time 168 190 169 191 /* Audio circular buffer */ 170 192 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 171 193 int raud, waud; /* read and write positions */ 172 intaudbuf_timecode; /* timecode of audio most recently placed into194 long long audbuf_timecode; /* timecode of audio most recently placed into 173 195 buffer */ 174 196 175 197 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
15 15 16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 #include "audiooutputdigitalencoder.h" 19 #include "SoundTouch.h" 20 #include "freesurround.h" 18 21 #include "compat.h" 19 22 20 23 #define LOC QString("AO: ") … … 36 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 37 40 audio_passthru(false), audio_stretchfactor(1.0f), 38 41 42 audio_codec(NULL), 39 43 source(lsource), killaudio(false), 40 44 41 45 pauseaudio(false), audio_actually_paused(false), … … 47 51 48 52 src_ctx(NULL), 49 53 50 pSoundStretch(NULL), blocking(false), 54 pSoundStretch(NULL), 55 encoder(NULL), 56 upmixer(NULL), 57 source_audio_channels(-1), 58 source_audio_bytes_per_sample(0), 59 needs_upmix(false), 51 60 61 blocking(false), 62 52 63 lastaudiolen(0), samples_buffered(0), 53 64 54 65 audio_thread_exists(false), … … 71 82 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 83 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 84 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 85 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 86 75 87 // You need to call Reconfigure from your concrete class. 76 88 // Reconfigure(laudio_bits, laudio_channels, … … 111 123 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 124 .arg(audio_stretchfactor)); 113 125 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 126 if (audio_codec) 127 { 128 if (!encoder) 129 { 130 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 131 encoder = new AudioOutputDigitalEncoder(); 132 if (!encoder->Init(audio_codec->codec_id, 133 audio_codec->bit_rate, 134 audio_codec->sample_rate, 135 audio_codec->channels 136 )) 137 { 138 // eeks 139 delete encoder; 140 encoder = NULL; 141 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 142 } 143 } 144 } 145 if (encoder) 146 { 147 pSoundStretch->setSampleRate(audio_codec->sample_rate); 148 pSoundStretch->setChannels(audio_codec->channels); 149 } 150 else 151 { 152 pSoundStretch->setSampleRate(audio_samplerate); 153 pSoundStretch->setChannels(audio_channels); 154 } 116 155 117 156 pSoundStretch->setTempo(audio_stretchfactor); 118 157 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 135 174 } 136 175 137 176 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 177 int laudio_samplerate, bool laudio_passthru, 178 void* laudio_codec) 139 179 { 180 int codec_id = CODEC_ID_NONE; 181 int lcodec_id = CODEC_ID_NONE; 182 int lcchannels = 0; 183 int cchannels = 0; 184 int lsource_audio_channels = laudio_channels; 185 bool lneeds_upmix = false; 186 187 if (laudio_codec) 188 { 189 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 190 laudio_bits = 16; 191 laudio_channels = 2; 192 lsource_audio_channels = laudio_channels; 193 laudio_samplerate = 48000; 194 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 195 } 196 if (audio_codec) 197 { 198 codec_id = audio_codec->codec_id; 199 cchannels = ((AVCodecContext*)audio_codec)->channels; 200 } 201 if ((configured_audio_channels == 6) && 202 //(configured_audio_channels != lsource_audio_channels) && 203 !(laudio_codec || audio_codec)) 204 { 205 laudio_channels = configured_audio_channels; 206 lneeds_upmix = true; 207 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 208 } 209 ClearError(); 140 210 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 211 laudio_samplerate == audio_samplerate && !need_resampler && 212 laudio_passthru == audio_passthru && 213 lneeds_upmix == needs_upmix && 214 lcodec_id == codec_id && lcchannels == cchannels) 215 { 216 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 217 return; 144 218 } 145 219 KillAudio(); 146 220 147 221 pthread_mutex_lock(&audio_buflock); … … 151 225 waud = raud = 0; 152 226 audio_actually_paused = false; 153 227 228 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 229 audio_channels = laudio_channels; 230 source_audio_channels = lsource_audio_channels; 155 231 audio_bits = laudio_bits; 156 232 audio_samplerate = laudio_samplerate; 233 audio_codec = (AVCodecContext*)laudio_codec; 157 234 audio_passthru = laudio_passthru; 235 needs_upmix = lneeds_upmix; 158 236 if (audio_bits != 8 && audio_bits != 16) 159 237 { 160 238 pthread_mutex_unlock(&avsync_lock); … … 163 241 return; 164 242 } 165 243 audio_bytes_per_sample = audio_channels * audio_bits / 8; 244 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 166 245 167 246 need_resampler = false; 168 247 killaudio = false; … … 172 251 173 252 numlowbuffer = 0; 174 253 254 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 255 .arg(audio_main_device).arg(audio_channels) 256 .arg(source_audio_channels).arg(audio_samplerate)); 257 175 258 // Actually do the device specific open call 176 259 if (!OpenDevice()) 177 260 { 178 261 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 262 pthread_mutex_unlock(&avsync_lock); 180 263 pthread_mutex_unlock(&audio_buflock); 264 if (GetError().isEmpty()) 265 Error("Aborting reconfigure"); 266 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 267 return; 182 268 } 183 269 … … 200 286 current_seconds = -1; 201 287 source_bitrate = -1; 202 288 289 // NOTE: this wont do anything as above samplerate vars are set equal 203 290 // Check if we need the resampler 204 291 if (audio_samplerate != laudio_samplerate) 205 292 { … … 222 309 need_resampler = true; 223 310 } 224 311 312 if (needs_upmix) 313 { 314 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 315 upmixer = new FreeSurround(audio_samplerate, source == AUDIOOUTPUT_VIDEO); 316 VERBOSE(VB_AUDIO, LOC + QString("create upmixer done")); 317 } 318 225 319 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 320 .arg(audio_stretchfactor)); 321 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 322 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 227 323 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 324 if (redo_stretch) 230 325 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 326 float laudio_stretchfactor = audio_stretchfactor; 327 delete pSoundStretch; 328 pSoundStretch = NULL; 329 audio_stretchfactor = 0.0; 330 SetStretchFactorLocked(laudio_stretchfactor); 233 331 } 332 else 333 { 334 SetStretchFactorLocked(audio_stretchfactor); 335 if (pSoundStretch) 336 { 337 // if its passthru then we need to reencode 338 if (audio_codec) 339 { 340 if (!encoder) 341 { 342 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 343 encoder = new AudioOutputDigitalEncoder(); 344 if (!encoder->Init(audio_codec->codec_id, 345 audio_codec->bit_rate, 346 audio_codec->sample_rate, 347 audio_codec->channels 348 )) 349 { 350 // eeks 351 delete encoder; 352 encoder = NULL; 353 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 354 } 355 } 356 } 357 if (encoder) 358 { 359 pSoundStretch->setSampleRate(audio_codec->sample_rate); 360 pSoundStretch->setChannels(audio_codec->channels); 361 } 362 else 363 { 364 pSoundStretch->setSampleRate(audio_samplerate); 365 pSoundStretch->setChannels(audio_channels); 366 } 367 } 368 } 234 369 235 370 // Setup visualisations, zero the visualisations buffers 236 371 prepareVisuals(); … … 290 425 pSoundStretch = NULL; 291 426 } 292 427 428 if (encoder) 429 { 430 delete encoder; 431 encoder = NULL; 432 } 433 434 if (upmixer) 435 { 436 delete upmixer; 437 upmixer = NULL; 438 } 439 needs_upmix = false; 440 293 441 CloseDevice(); 294 442 295 443 killAudioLock.unlock(); … … 303 451 304 452 void AudioOutputBase::Pause(bool paused) 305 453 { 454 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 306 455 pauseaudio = paused; 307 456 audio_actually_paused = false; 308 457 } … … 385 534 The reason is that computing 'audiotime' requires acquiring the audio 386 535 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 536 from the audio thread, and then call this from the video thread. */ 388 intret;537 long long ret; 389 538 struct timeval now; 390 539 391 540 if (audiotime == 0) … … 397 546 398 547 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 548 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);549 ret = (long long)(ret * audio_stretchfactor); 401 550 551 #if 1 552 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 553 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 554 .arg(now.tv_sec).arg(now.tv_usec) 555 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 556 .arg(ret) 557 .arg(audiotime) 558 .arg(audio_stretchfactor) 559 ); 560 #endif 561 402 562 ret += audiotime; 403 563 404 564 pthread_mutex_unlock(&avsync_lock); 405 return ret;565 return (int)ret; 406 566 } 407 567 408 568 void AudioOutputBase::SetAudiotime(void) … … 439 599 // include algorithmic latencies 440 600 if (pSoundStretch) 441 601 { 602 // add the effect of any unused but processed samples, AC3 reencode does this 603 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 442 604 // add the effect of unprocessed samples in time stretch algo 443 605 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 606 audio_bytes_per_sample) / audio_stretchfactor); 445 607 } 446 608 609 if (upmixer && needs_upmix) 610 { 611 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 612 } 613 447 614 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 615 (audio_bytes_per_sample * effdspstretched)); 449 616 450 617 gettimeofday(&audiotime_updated, NULL); 618 #if 1 619 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 620 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 621 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 622 .arg(audiotime) 623 .arg(audbuf_timecode) 624 .arg(totalbuffer) 625 .arg(soundcard_buffer) 626 .arg(effdspstretched) 627 .arg(audio_bytes_per_sample) 628 .arg(audio_stretchfactor) 629 ); 630 #endif 451 631 452 632 pthread_mutex_unlock(&avsync_lock); 453 633 pthread_mutex_unlock(&audio_buflock); … … 464 644 if (need_resampler && src_ctx) 465 645 len = (int)ceilf(float(len) * src_data.src_ratio); 466 646 647 // include samples in upmix buffer that may be flushed 648 if (needs_upmix && upmixer) 649 len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample; 650 467 651 if ((len > afree) && !blocking) 468 652 { 469 653 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( … … 515 699 // NOTE: This function is not threadsafe 516 700 517 701 int afree = audiofree(true); 518 int len = samples * audio_bytes_per_sample;702 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 519 703 520 704 // Check we have enough space to write the data 521 705 if (need_resampler && src_ctx) 522 706 len = (int)ceilf(float(len) * src_data.src_ratio); 523 707 708 // include samples in upmix buffer that may be flushed 709 if (needs_upmix && upmixer) 710 len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample; 711 524 712 if ((len > afree) && !blocking) 525 713 { 526 714 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( 527 715 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 528 716 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 529 717 .arg(timecode)); 530 531 718 return false; // would overflow 532 719 } 533 720 … … 564 751 565 752 int AudioOutputBase::WaitForFreeSpace(int samples) 566 753 { 567 int len = samples * audio_bytes_per_sample; 754 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 755 int len = samples * abps; 568 756 int afree = audiofree(false); 569 757 570 758 while (len > afree) 571 759 { 572 760 if (blocking) 573 761 { 574 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +762 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 575 763 QString("(need %1, available %2)").arg(len).arg(afree)); 576 764 577 765 // wait for more space … … 580 768 } 581 769 else 582 770 { 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; 771 VERBOSE(VB_IMPORTANT, LOC_ERR + 772 QString("Audio buffer overflow, %1 audio samples lost!") 773 .arg(samples-afree / abps)); 774 samples = afree / abps; 775 len = samples * abps; 587 776 if (src_ctx) 588 777 { 589 778 int error = src_reset(src_ctx); … … 608 797 609 798 int afree = audiofree(false); 610 799 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)); 800 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 801 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 802 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6 upmixer %7") 803 .arg(samples) 804 .arg(samples * abps) 805 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 806 .arg(needs_upmix).arg((uint)(void*)upmixer) 807 ); 615 808 616 len = WaitForFreeSpace(samples); 617 618 if (interleaved) 809 if (upmixer && needs_upmix) 619 810 { 620 char *mybuf = (char*)buffer; 621 int bdiff = AUDBUFSIZE - org_waud; 622 if (bdiff < len) 811 int out_samples = 0; 812 int step = (interleaved)?source_audio_channels:1; 813 len = WaitForFreeSpace(samples); // test 814 for(int itemp=0; itemp<samples; ) 623 815 { 624 memcpy(audiobuffer + org_waud, mybuf, bdiff); 625 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 816 if (audio_bytes == 2) 817 itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 818 else 819 itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 820 821 int copy_samples = upmixer->numSamples(); 822 if (copy_samples) 823 { 824 int copy_len = copy_samples * abps; 825 out_samples += copy_samples; 826 if (out_samples > samples) 827 len = WaitForFreeSpace(out_samples); 828 int bdiff = AUDBUFSIZE - org_waud; 829 if (bdiff < copy_len) 830 { 831 int bdiff_samples = bdiff/abps; 832 upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples); 833 upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples)); 834 } 835 else 836 { 837 upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples); 838 } 839 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 840 } 626 841 } 627 else 628 memcpy(audiobuffer + org_waud, mybuf, len); 629 630 org_waud = (org_waud + len) % AUDBUFSIZE; 631 } 632 else 842 if (samples > 0) 843 { 844 len = WaitForFreeSpace(out_samples); 845 } 846 samples = out_samples; 847 } 848 else 633 849 { 634 char **mybuf = (char**)buffer; 635 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 850 len = WaitForFreeSpace(samples); 851 852 if (interleaved) 636 853 { 637 for (int chan = 0; chan < audio_channels; chan++) 854 char *mybuf = (char*)buffer; 855 int bdiff = AUDBUFSIZE - org_waud; 856 if (bdiff < len) 638 857 { 639 audiobuffer[org_waud++] = mybuf[chan][itemp]; 640 if (audio_bits == 16) 641 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 858 memcpy(audiobuffer + org_waud, mybuf, bdiff); 859 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 860 } 861 else 862 memcpy(audiobuffer + org_waud, mybuf, len); 863 864 org_waud = (org_waud + len) % AUDBUFSIZE; 865 } 866 else 867 { 868 char **mybuf = (char**)buffer; 869 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 870 { 871 for (int chan = 0; chan < audio_channels; chan++) 872 { 873 audiobuffer[org_waud++] = mybuf[chan][itemp]; 874 if (audio_bits == 16) 875 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 642 876 643 if (org_waud >= AUDBUFSIZE) 644 org_waud -= AUDBUFSIZE; 877 if (org_waud >= AUDBUFSIZE) 878 org_waud -= AUDBUFSIZE; 879 } 645 880 } 646 881 } 647 882 } 648 883 649 if ( pSoundStretch)884 if (samples > 0) 650 885 { 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) 886 if (pSoundStretch) 657 887 { 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 else664 {665 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +666 org_waud), len / audio_bytes_per_sample);667 }668 888 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) 889 // does not change the timecode, only the number of samples 890 // back to orig pos 891 org_waud = waud; 892 int bdiff = AUDBUFSIZE - org_waud; 893 int nSamplesToEnd = bdiff/abps; 894 if (bdiff < len) 677 895 { 678 samplesToGet = nSamplesToEnd; 896 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 897 org_waud), nSamplesToEnd); 898 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 899 (len - bdiff) / abps); 679 900 } 901 else 902 { 903 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 904 org_waud), len / abps); 905 } 680 906 681 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 682 (audiobuffer + org_waud), samplesToGet); 683 if (nSamples == nSamplesToEnd) 907 if (encoder) 684 908 { 685 org_waud = 0; 686 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 909 // pull out a packet's worth and reencode it until we dont have enough 910 // for any more packets 911 soundtouch::SAMPLETYPE* temp_buff = 912 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 913 size_t frameSize = encoder->FrameSize()/abps; 914 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 915 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 916 .arg(frameSize) 917 .arg(encoder->FrameSize()) 918 .arg(pSoundStretch->numSamples()) 919 ); 920 // process the same number of samples as it creates a full encoded buffer 921 // just like before 922 while (pSoundStretch->numSamples() >= frameSize) 923 { 924 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 925 int amount = encoder->Encode(temp_buff); 926 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 927 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 928 .arg(amount) 929 .arg(got) 930 .arg(pSoundStretch->numSamples()) 931 ); 932 if (amount == 0) 933 continue; 934 //len = WaitForFreeSpace(amount); 935 char * ob = encoder->GetOutBuff(); 936 if (amount >= bdiff) 937 { 938 memcpy(audiobuffer + org_waud, ob, bdiff); 939 ob += bdiff; 940 amount -= bdiff; 941 org_waud = 0; 942 } 943 if (amount > 0) 944 memcpy(audiobuffer + org_waud, ob, amount); 945 bdiff = AUDBUFSIZE - amount; 946 org_waud += amount; 947 } 687 948 } 688 949 else 689 950 { 690 org_waud += nSamples * audio_bytes_per_sample; 691 nSamplesToEnd -= nSamples; 951 int newLen = 0; 952 int nSamples; 953 len = WaitForFreeSpace(pSoundStretch->numSamples() * 954 audio_bytes_per_sample); 955 do 956 { 957 int samplesToGet = len/audio_bytes_per_sample; 958 if (samplesToGet > nSamplesToEnd) 959 { 960 samplesToGet = nSamplesToEnd; 961 } 962 963 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 964 (audiobuffer + org_waud), samplesToGet); 965 if (nSamples == nSamplesToEnd) 966 { 967 org_waud = 0; 968 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 969 } 970 else 971 { 972 org_waud += nSamples * audio_bytes_per_sample; 973 nSamplesToEnd -= nSamples; 974 } 975 976 newLen += nSamples * audio_bytes_per_sample; 977 len -= nSamples * audio_bytes_per_sample; 978 } while (nSamples > 0); 692 979 } 980 } 693 981 694 newLen += nSamples * audio_bytes_per_sample; 695 len -= nSamples * audio_bytes_per_sample; 696 } while (nSamples > 0); 697 } 982 waud = org_waud; 983 lastaudiolen = audiolen(false); 698 984 699 waud = org_waud; 700 lastaudiolen = audiolen(false); 985 if (timecode < 0) 986 { 987 // mythmusic doesn't give timestamps.. 988 timecode = (int)((samples_buffered * 100000.0) / effdsp); 989 } 990 991 samples_buffered += samples; 992 993 /* we want the time at the end -- but the file format stores 994 time at the start of the chunk. */ 995 // even with timestretch, timecode is still calculated from original 996 // sample count 997 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 701 998 702 samples_buffered += samples; 703 704 if (timecode < 0) 705 { 706 // mythmusic doesn't give timestamps.. 707 timecode = (int)((samples_buffered * 100000.0) / effdsp); 999 if (interleaved) 1000 dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits); 708 1001 } 709 710 /* we want the time at the end -- but the file format stores711 time at the start of the chunk. */712 // even with timestretch, timecode is still calculated from original713 // sample count714 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);715 1002 716 if (interleaved)717 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);718 719 1003 pthread_mutex_unlock(&audio_buflock); 720 1004 } 721 1005 … … 728 1012 729 1013 if (source_bitrate == -1) 730 1014 { 731 source_bitrate = audio_samplerate * audio_channels * audio_bits;1015 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 732 1016 } 733 1017 734 1018 if (ct / 1000 != current_seconds) … … 736 1020 current_seconds = ct / 1000; 737 1021 OutputEvent e(current_seconds, ct, 738 1022 source_bitrate, audio_samplerate, audio_bits, 739 audio_channels);1023 source_audio_channels); 740 1024 dispatch(e); 741 1025 } 742 1026 } … … 769 1053 space_on_soundcard = getSpaceOnSoundcard(); 770 1054 771 1055 if (space_on_soundcard != last_space_on_soundcard) { 772 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1056 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 773 1057 .arg(space_on_soundcard)); 774 1058 last_space_on_soundcard = space_on_soundcard; 775 1059 } … … 782 1066 WriteAudio(zeros, fragment_size); 783 1067 } else { 784 1068 // this should never happen now -dag 785 VERBOSE(VB_AUDIO , LOC +1069 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 786 1070 QString("waiting for space on soundcard " 787 1071 "to write zeros: have %1 need %2") 788 1072 .arg(space_on_soundcard).arg(fragment_size)); … … 818 1102 if (fragment_size > audiolen(true)) 819 1103 { 820 1104 if (audiolen(true) > 0) // only log if we're sending some audio 821 VERBOSE(VB_AUDIO , LOC +1105 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1106 QString("audio waiting for buffer to fill: " 823 1107 "have %1 want %2") 824 1108 .arg(audiolen(true)).arg(fragment_size)); 825 1109 826 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1110 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 827 1111 pthread_mutex_lock(&audio_buflock); 828 1112 pthread_cond_broadcast(&audio_bufsig); 829 1113 pthread_mutex_unlock(&audio_buflock); … … 837 1121 if (fragment_size > space_on_soundcard) 838 1122 { 839 1123 if (space_on_soundcard != last_space_on_soundcard) { 840 VERBOSE(VB_AUDIO , LOC +1124 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 841 1125 QString("audio waiting for space on soundcard: " 842 1126 "have %1 need %2") 843 1127 .arg(space_on_soundcard).arg(fragment_size)); … … 899 1183 900 1184 /* update raud */ 901 1185 raud = (raud + fragment_size) % AUDBUFSIZE; 902 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1186 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 903 1187 pthread_cond_broadcast(&audio_bufsig); 904 1188 905 1189 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
52 52 QString real_device = (audio_passthru) ? 53 53 audio_passthru_device : audio_main_device; 54 54 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 55 64 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 65 .arg(real_device)); 57 66 … … 89 98 } 90 99 else 91 100 { 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 94 105 period_time = buffer_time / 4; // 4 interrupts per buffer 95 106 } 96 107 … … 162 173 163 174 tmpbuf = aubuf; 164 175 165 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")176 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 177 .arg(size).arg(frames)); 167 178 168 179 while (frames > 0) -
programs/mythfrontend/globalsettings.cpp
57 57 #endif 58 58 #ifdef USING_ALSA 59 59 gc->addSelection("ALSA:default", "ALSA:default"); 60 gc->addSelection("ALSA:surround51", "ALSA:surround51"); 61 gc->addSelection("ALSA:analog", "ALSA:analog"); 62 gc->addSelection("ALSA:digital", "ALSA:digital"); 63 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 64 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 60 65 #endif 61 66 #ifdef USING_ARTS 62 67 gc->addSelection("ARTS:", "ARTS:"); … … 78 83 return gc; 79 84 } 80 85 86 static 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 Ch"), "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 81 98 static HostComboBox *PassThroughOutputDevice() 82 99 { 83 100 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3143 3160 new VerticalConfigurationGroup(false, false, true, true); 3144 3161 vgrp0->addChild(AC3PassThrough()); 3145 3162 vgrp0->addChild(DTSPassThrough()); 3163 addChild(MaxAudioChannels()); 3146 3164 3147 3165 VerticalConfigurationGroup *vgrp1 = 3148 3166 new VerticalConfigurationGroup(false, false, true, true); -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 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) 59 60 { 61 ClearError(); 60 62 (void)audio_samplerate; 61 63 (void)audio_passthru; 62 64 bits = audio_bits; 63 65 channels = audio_channels; 64 66 bytes_per_sample = bits * channels / 8; 67 if (channels>2) 68 Error("Invalid channel count"); 65 69 } 66 70 67 71 // dsprate is in 100 * samples/second -
programs/mythuitest/mythuitest.pro
6 6 TARGET = mythuitest 7 7 CONFIG += thread opengl 8 8 9 LIBS += -L../../libs/libavcodec -L../../libs/libavutil 10 LIBS += -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION 9 11 LIBS += $$EXTRA_LIBS 10 12 13 TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 14 TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB} 15 11 16 macx { 12 17 # Duplication of source with libmyth (e.g. oldsettings.cpp) 13 18 # means that the linker complains, so we have to ignore duplicates -
libs/libmythtv/avformatdecoder.h
259 259 bool allow_ac3_passthru; 260 260 bool allow_dts_passthru; 261 261 bool disable_passthru; 262 int max_channels; 262 263 263 264 AudioInfo audioIn; 264 265 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
51 51 52 52 #define MAX_AC3_FRAME_SIZE 6144 53 53 54 /** Set to zero to allow any number of AC3 channels. */55 #define MAX_OUTPUT_CHANNELS 256 57 54 static int cc608_parity(uint8_t byte); 58 55 static int cc608_good_parity(const int *parity_table, uint16_t data); 59 56 static void cc608_build_parity_table(int *parity_table); … … 417 414 418 415 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 419 416 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 417 max_channels = gContext->GetNumSetting("MaxChannels", 2); 420 418 421 419 audioIn.sample_size = -32; // force SetupAudioStream to run once 422 420 itv = GetNVP()->GetInteractiveTV(); … … 1580 1578 <<") already open, leaving it alone."); 1581 1579 } 1582 1580 //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)); 1583 1582 1583 #if 0 1584 // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this 1584 1585 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1585 1586 if (enc->codec_id == CODEC_ID_DTS) 1586 1587 { … … 1589 1590 // enc->bit_rate = what??; 1590 1591 } 1591 1592 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1593 #endif 1592 1594 1593 1595 bitrate += enc->bit_rate; 1594 1596 break; … … 3260 3262 if (!curstream->codec->channels) 3261 3263 { 3262 3264 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; 3264 3267 ret = avcodec_decode_audio( 3265 3268 curstream->codec, audioSamples, 3266 3269 &data_size, ptr, len); … … 3321 3324 AVCodecContext *ctx = curstream->codec; 3322 3325 3323 3326 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; 3326 3329 3327 3330 ret = avcodec_decode_audio( 3328 3331 ctx, audioSamples, &data_size, ptr, len); … … 3675 3678 3676 3679 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3677 3680 { 3681 // can only disable never reenable as once timestretch is on its on for the session 3682 if (disable_passthru) 3683 return; 3678 3684 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3679 3685 { 3680 3686 disable_passthru = disable; … … 3707 3713 AVCodecContext *codec_ctx = NULL; 3708 3714 AudioInfo old_in = audioIn; 3709 3715 AudioInfo old_out = audioOut; 3716 bool using_passthru = false; 3710 3717 3711 3718 if ((currentTrack[kTrackTypeAudio] >= 0) && 3712 3719 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3718 3725 assert(curstream->codec); 3719 3726 codec_ctx = curstream->codec; 3720 3727 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3721 !disable_passthru &&3722 3728 (codec_ctx->codec_id == CODEC_ID_AC3)); 3723 3729 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3724 !disable_passthru &&3725 3730 (codec_ctx->codec_id == CODEC_ID_DTS)); 3731 using_passthru = do_ac3_passthru || do_dts_passthru; 3726 3732 info = AudioInfo(codec_ctx->codec_id, 3727 3733 codec_ctx->sample_rate, codec_ctx->channels, 3728 do_ac3_passthru || do_dts_passthru);3734 using_passthru && !disable_passthru); 3729 3735 } 3730 3736 3731 3737 if (info == audioIn) 3732 3738 return false; // no change 3733 3739 3740 QString ptmsg = ""; 3741 if (using_passthru) 3742 { 3743 ptmsg = QString(" using passthru"); 3744 } 3734 3745 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3735 3746 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3736 3747 3737 3748 audioOut = audioIn = info; 3738 if ( audioIn.do_passthru)3749 if (using_passthru) 3739 3750 { 3740 3751 // 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; 3744 3780 } 3745 3781 else 3746 3782 { 3747 if (audioOut.channels > MAX_OUTPUT_CHANNELS)3783 if (audioOut.channels > max_channels) 3748 3784 { 3749 audioOut.channels = MAX_OUTPUT_CHANNELS;3785 audioOut.channels = max_channels; 3750 3786 audioOut.sample_size = audioOut.channels * 2; 3751 codec_ctx->channels = MAX_OUTPUT_CHANNELS;3787 codec_ctx->channels = audioOut.channels; 3752 3788 } 3753 3789 } 3790 bool audiook; 3754 3791 3755 3792 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 3756 3793 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 3763 3800 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3764 3801 audioOut.sample_rate, 3765 3802 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(); 3767 3807 3768 3808 return true; 3769 3809 } -
libs/libmythtv/NuppelVideoPlayer.h
127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 void SetAudioCodec(void *ac); 130 131 131 132 // Sets 132 133 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 682 683 int audio_bits; 683 684 int audio_samplerate; 684 685 float audio_stretchfactor; 686 void *audio_codec; 685 687 bool audio_passthru; 686 688 687 689 // Picture-in-Picture -
libs/libmythtv/NuppelVideoPlayer.cpp
206 206 audio_passthru_device(QString::null), 207 207 audio_channels(2), audio_bits(-1), 208 208 audio_samplerate(44100), audio_stretchfactor(1.0f), 209 audio_codec(NULL), 209 210 // Picture-in-Picture 210 211 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 211 212 // Preview window support … … 767 768 if (audioOutput) 768 769 { 769 770 audioOutput->Reconfigure(audio_bits, audio_channels, 770 audio_samplerate, audio_passthru); 771 audio_samplerate, audio_passthru, 772 audio_codec); 771 773 errMsg = audioOutput->GetError(); 772 774 if (!errMsg.isEmpty()) 773 775 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3650 3657 audio_passthru = passthru; 3651 3658 } 3652 3659 3660 void NuppelVideoPlayer::SetAudioCodec(void* ac) 3661 { 3662 audio_codec = ac; 3663 } 3664 3653 3665 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3654 3666 { 3655 3667 if (audioOutput) -
libs/libavcodec/liba52.c
134 134 } 135 135 } 136 136 137 static inline int16_t convert(int32_t i) 138 { 139 return av_clip_int16(i - 0x43c00000); 140 } 141 142 void 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 153 void 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 166 void 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 181 int 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 193 void 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 137 312 /**** end */ 138 313 139 314 #define HEADER_SIZE 7 … … 177 352 /* update codec info */ 178 353 avctx->sample_rate = sample_rate; 179 354 s->channels = ac3_channels[s->flags & 7]; 355 if (avctx->cqp >= 0) 356 avctx->channels = avctx->cqp; 180 357 if (s->flags & A52_LFE) 181 358 s->channels++; 182 359 if (avctx->channels == 0) … … 199 376 s->inbuf_ptr += len; 200 377 buf_size -= len; 201 378 } else { 379 int chans; 202 380 flags = s->flags; 203 381 if (avctx->channels == 1) 204 382 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 } 207 389 else 208 390 flags |= A52_ADJUST_LEVEL; 209 391 level = 1; 392 chans = channels_multi(flags); 210 393 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 211 394 fail: 212 395 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 217 400 for (i = 0; i < 6; i++) { 218 401 if (s->a52_block(s->state)) 219 402 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); 221 404 } 222 405 s->inbuf_ptr = s->inbuf; 223 406 s->frame_size = 0; -
libs/libavcodec/ac3_parser.c
84 84 return 0; 85 85 } 86 86 87 staticint 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, 88 88 int *bit_rate, int *samples) 89 89 { 90 90 int err;