Ticket #1104: mythtv_ac3.33.patch
File mythtv_ac3.33.patch, 100.5 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 #pragma comment (lib,"libfftw3f-3.lib") 26 27 typedef std::complex<float> cfloat; 28 29 const float PI = 3.141592654; 30 const float epsilon = 0.000001; 31 const float center_level = 0.5*sqrt(0.5); // gain of the center channel 32 33 // private implementation of the surround decoder 34 class decoder_impl { 35 public: 36 // create an instance of the decoder 37 // blocksize is fixed over the lifetime of this object for performance reasons 38 decoder_impl(unsigned blocksize=8192): N(blocksize) { 39 // create FFTW buffers 40 lt = (float*)fftwf_malloc(sizeof(float)*N); 41 rt = (float*)fftwf_malloc(sizeof(float)*N); 42 dst = (float*)fftwf_malloc(sizeof(float)*N); 43 dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N); 44 dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N); 45 src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N); 46 loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE); 47 loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE); 48 store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE); 49 // resize our own buffers 50 frontR.resize(N); 51 frontL.resize(N); 52 avg.resize(N); 53 surR.resize(N); 54 surL.resize(N); 55 xfs.resize(N); 56 yfs.resize(N); 57 inbuf[0].resize(N + N/2); 58 inbuf[1].resize(N + N/2); 59 for (unsigned c=0;c<6;c++) { 60 outbuf[c].resize(N + N/2); 61 filter[c].resize(N); 62 } 63 // lfe filter is just straight through 64 for (unsigned f=0;f<=N/2;f++) { 65 filter[5][f] = 1.0; 66 } 67 // generate the window function (square root of hann, b/c it is applied before and after the transform) 68 wnd.resize(N); 69 for (unsigned k=0;k<N;k++) 70 wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))); 71 // set the default coefficients 72 surround_coefficients(0.8165,0.5774); 73 phase_mode(0); 74 separation(1,1); 75 steering_mode(1); 76 } 77 78 // destructor 79 ~decoder_impl() { 80 // clean up the FFTW stuff 81 fftwf_destroy_plan(store); 82 fftwf_destroy_plan(loadR); 83 fftwf_destroy_plan(loadL); 84 fftwf_free(src); 85 fftwf_free(dftR); 86 fftwf_free(dftL); 87 fftwf_free(dst); 88 fftwf_free(rt); 89 fftwf_free(lt); 90 } 91 92 // decode a chunk of stereo sound, has to contain exactly blocksize samples 93 // center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution 94 // dimension [0..1] moves the soundfield backwards, 0=front, 1=side 95 // adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption 96 void decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 97 // append incoming data to the end of the input buffer 98 for (unsigned k=0;k<N;k++) { 99 inbuf[0][k+N/2] = input[0][k]; 100 inbuf[1][k+N/2] = input[1][k]; 101 } 102 // process first part 103 float *in_first[2] = {&inbuf[0][0],&inbuf[1][0]}; 104 add_output(in_first,output,center_width,dimension,adaption_rate); 105 // process second part (overlapped) and return result 106 float *in_second[2] = {&inbuf[0][N/2],&inbuf[1][N/2]}; 107 add_output(in_second,output,center_width,dimension,adaption_rate,true); 108 // shift last third of input buffer to the beginning 109 for (unsigned k=0;k<N/2;k++) { 110 inbuf[0][k] = inbuf[0][k+N]; 111 inbuf[1][k] = inbuf[1][k+N]; 112 } 113 } 114 115 // flush the internal buffers 116 void flush() { 117 for (unsigned k=0;k<N+N/2;k++) { 118 for (unsigned c=0;c<6;c++) 119 outbuf[c][k] = 0; 120 inbuf[0][k] = 0; 121 inbuf[1][k] = 0; 122 } 123 } 124 125 // set the assumed surround mixing coefficients 126 void surround_coefficients(float a, float b) { 127 master_gain = 1.0; 128 // calc the simple coefficients 129 surround_high = a; 130 surround_low = b; 131 surround_balance = (a-b)/(a+b); 132 surround_level = 1/(a+b); 133 // calc the linear coefficients 134 cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0); 135 A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n; 136 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 137 } 138 139 // set the phase shifting mode 140 void phase_mode(unsigned mode) { 141 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; 142 phase_offsetL = modes[mode][0]; 143 phase_offsetR = modes[mode][1]; 144 } 145 146 // what steering mode should be chosen 147 void steering_mode(bool mode) { linear_steering = mode; } 148 149 // set front & rear separation controls 150 void separation(float front, float rear) { 151 front_separation = front; 152 rear_separation = rear; 153 } 154 155 private: 156 // polar <-> cartesian coodinates conversion 157 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); } 158 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); } 159 static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); } 160 static inline float sqr(float x) { return x*x; } 161 // the dreaded min/max 162 static inline float min(float a, float b) { return a<b?a:b; } 163 static inline float max(float a, float b) { return a>b?a:b; } 164 static inline float clamp(float x) { return max(-1,min(1,x)); } 165 166 // handle the output buffering for overlapped calls of block_decode 167 void add_output(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate, bool result=false) { 168 // add the windowed data to the last 2/3 of the output buffer 169 float *out[6] = {&outbuf[0][N/2],&outbuf[1][N/2],&outbuf[2][N/2],&outbuf[3][N/2],&outbuf[4][N/2],&outbuf[5][N/2]}; 170 block_decode(input,out,center_width,dimension,adaption_rate); 171 for (unsigned c=0;c<6;c++) { 172 if (result) 173 // return the first 2/3 of the ouput buffer 174 for (unsigned k=0;k<N;k++) 175 output[c][k] = outbuf[c][k]; 176 for (unsigned k=0;k<N;k++) 177 // shift the last 2/3 to the first 2/3 of the output buffer 178 outbuf[c][k] = outbuf[c][k+N/2]; 179 // and clear the rest 180 for (unsigned k=N;k<N+N/2;k++) 181 outbuf[c][k] = 0; 182 } 183 } 184 185 // CORE FUNCTION: decode a block of data 186 void block_decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 187 // 1. scale the input by the window function; this serves a dual purpose: 188 // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed 189 // - second it allows for smooth blending of varying filters between the blocks 190 for (unsigned k=0;k<N;k++) { 191 lt[k] = input[0][k] * wnd[k] * master_gain; 192 rt[k] = input[1][k] * wnd[k] * master_gain; 193 } 194 195 // ... and tranform it into the frequency domain 196 fftwf_execute(loadL); 197 fftwf_execute(loadR); 198 199 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 200 for (unsigned f=0;f<=N/2;f++) { 201 // get left/right amplitudes/phases 202 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 203 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); 204 // if (ampL+ampR < epsilon) 205 // continue; 206 207 // calculate the amplitude/phase difference 208 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 209 float phaseDiff = phaseL - phaseR; 210 if (phaseDiff < -PI) phaseDiff += 2*PI; 211 if (phaseDiff > PI) phaseDiff -= 2*PI; 212 phaseDiff = abs(phaseDiff); 213 214 if (linear_steering) { 215 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2); 216 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */ 217 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real(); 218 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G); 219 220 /* 221 Problem: 222 This assumes that the values are interpolated linearly between the cardinal points. 223 But this way we have no chance of knowing the average volume... 224 - Can we solve that computing everything under the assumption of normalized volume? 225 No. Seemingly not. 226 - Maybe we should add w explitcitly into the equation and see if we can solve it... 227 */ 228 229 230 //cfloat lt(0.5,0),rt(0.5,0); 231 //cfloat x(0,0), y(1,0); 232 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E); 233 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E); 234 cfloat s = sqrt(p*p/4.0f - q); 235 cfloat x = -p; 236 cfloat x1 = -p/2.0f + s; 237 cfloat x2 = -p/2.0f - s; 238 float x = 0; 239 if (x1.real() >= -1 && x1.real() <= 1) 240 x = x1.real(); 241 else if (x2.real() >= -1 && x2.real() <= 1) 242 x = x2.real();*/ 243 244 //cfloat yp = (rt - (x*E+H))/(F+x*G); 245 //cfloat xp = (lt - (y*B+D))/(A+y*C); 246 247 /*xfs[f] = x; 248 yfs[f] = y.real();*/ 249 250 // --- this is the fancy new linear mode --- 251 252 // get sound field x/y position 253 yfs[f] = get_yfs(ampDiff,phaseDiff); 254 xfs[f] = get_xfs(ampDiff,yfs[f]); 255 256 // add dimension control 257 yfs[f] = clamp(yfs[f] - dimension); 258 259 // add crossfeed control 260 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 261 262 // 3. generate frequency filters for each output channel 263 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 264 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 265 float volume[5] = { 266 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 267 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 268 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 269 back * surround_level * left, // left surround 270 back * surround_level * right // right surround 271 }; 272 273 // adapt the prior filter 274 for (unsigned c=0;c<5;c++) 275 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N; 276 277 } else { 278 // --- this is the old & simple steering mode --- 279 280 // calculate the amplitude/phase difference 281 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 282 float phaseDiff = phaseL - phaseR; 283 if (phaseDiff < -PI) phaseDiff += 2*PI; 284 if (phaseDiff > PI) phaseDiff -= 2*PI; 285 phaseDiff = abs(phaseDiff); 286 287 // determine sound field x-position 288 xfs[f] = ampDiff; 289 290 // determine preliminary sound field y-position from phase difference 291 yfs[f] = 1 - (phaseDiff/PI)*2; 292 293 if (abs(xfs[f]) > surround_balance) { 294 // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance 295 // this is necessary because the sound field is trapezoidal and will be stretched behind the listener 296 float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance); 297 yfs[f] = (1-frontness) * yfs[f] + frontness * 1; 298 } 299 300 // add dimension control 301 yfs[f] = clamp(yfs[f] - dimension); 302 303 // add crossfeed control 304 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 305 306 // 3. generate frequency filters for each output channel, according to the signal position 307 // the sum of all channel volumes must be 1.0 308 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 309 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 310 float volume[5] = { 311 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 312 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 313 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 314 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))), // left surround 315 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2))) // right surround 316 }; 317 318 // adapt the prior filter 319 for (unsigned c=0;c<5;c++) 320 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N; 321 } 322 323 // ... and build the signal which we want to position 324 frontL[f] = polar(ampL+ampR,phaseL); 325 frontR[f] = polar(ampL+ampR,phaseR); 326 avg[f] = frontL[f] + frontR[f]; 327 surL[f] = polar(ampL+ampR,phaseL+phase_offsetL); 328 surR[f] = polar(ampL+ampR,phaseR+phase_offsetR); 329 } 330 331 // 4. distribute the unfiltered reference signals over the channels 332 apply_filter(&frontL[0],&filter[0][0],&output[0][0]); // front left 333 apply_filter(&avg[0], &filter[1][0],&output[1][0]); // front center 334 apply_filter(&frontR[0],&filter[2][0],&output[2][0]); // front right 335 apply_filter(&surL[0],&filter[3][0],&output[3][0]); // surround left 336 apply_filter(&surR[0],&filter[4][0],&output[4][0]); // surround right 337 apply_filter(&avg[0],&filter[5][0],&output[5][0]); // lfe 338 } 339 340 // map from amplitude difference and phase difference to yfs 341 inline double get_yfs(double ampDiff, double phaseDiff) { 342 double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2); 343 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 344 + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x)); 345 } 346 347 // map from amplitude difference and yfs to xfs 348 inline double get_xfs(double ampDiff, double yfs) { 349 double x=ampDiff,y=yfs; 350 return 2.464833559224702*x - 423.52131153259404*x*y + 351 67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y - 352 79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y + 353 35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) - 354 2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) - 355 12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) + 356 1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) + 357 12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) - 358 91.21223198407546*tan(x)*tan(y); 359 } 360 361 // filter the complex source signal and add it to target 362 void apply_filter(cfloat *signal, float *flt, float *target) { 363 // filter the signal 364 for (unsigned f=0;f<=N/2;f++) { 365 src[f][0] = signal[f].real() * flt[f]; 366 src[f][1] = signal[f].imag() * flt[f]; 367 } 368 // transform into time domain 369 fftwf_execute(store); 370 // add the result to target, windowed 371 for (unsigned k=0;k<N;k++) 372 target[k] += wnd[k]*dst[k]; 373 } 374 375 unsigned N; // the block size 376 // FFTW data structures 377 float *lt,*rt,*dst; // left total, right total (source arrays), destination array 378 fftwf_complex *dftL,*dftR,*src; // intermediate arrays (FFTs of lt & rt, processing source) 379 fftwf_plan loadL,loadR,store; // plans for loading the data into the intermediate format and back 380 // buffers 381 std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain 382 std::vector<float> xfs,yfs; // the feature space positions for each frequency bin 383 std::vector<float> wnd; // the window function, precalculated 384 std::vector<float> filter[6]; // a frequency filter for each output channel 385 std::vector<float> inbuf[2]; // the sliding input buffers 386 std::vector<float> outbuf[6]; // the sliding output buffers 387 // coefficients 388 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 389 float surround_balance; // the xfs balance that follows from the coeffs 390 float surround_level; // gain for the surround channels (follows from the coeffs 391 float master_gain; // gain for all channels 392 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 393 float front_separation; // front stereo separation 394 float rear_separation; // rear stereo separation 395 bool linear_steering; // whether the steering should be linear or not 396 cfloat A,B,C,D,E,F,G,H; // coefficients for the linear steering 397 }; 398 399 400 // implementation of the shell class 401 402 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { } 403 404 fsurround_decoder::~fsurround_decoder() { delete impl; } 405 406 void fsurround_decoder::decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 407 impl->decode(input,output,center_width,dimension,adaption_rate); 408 } 409 410 void fsurround_decoder::flush() { impl->flush(); } 411 412 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 413 414 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 415 416 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); } 417 418 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 31 #include <qstring.h> 32 #include <qdatetime.h> 33 34 using namespace std; 35 36 #if 0 37 #define VERBOSE(args...) \ 38 do { \ 39 QDateTime dtmp = QDateTime::currentDateTime(); \ 40 QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \ 41 ostringstream verbose_macro_tmp; \ 42 verbose_macro_tmp << dtime << " " << args; \ 43 cout << verbose_macro_tmp.str() << endl; \ 44 } while (0) 45 #else 46 #define VERBOSE(args...) 47 #endif 48 #if 0 49 #define VERBOSE1(args...) \ 50 do { \ 51 QDateTime dtmp = QDateTime::currentDateTime(); \ 52 QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \ 53 ostringstream verbose_macro_tmp; \ 54 verbose_macro_tmp << dtime << " " << args; \ 55 cout << verbose_macro_tmp.str() << endl; \ 56 } while (0) 57 #else 58 #define VERBOSE1(args...) 59 #endif 60 61 // our default internal block size, in floats 62 const unsigned block_size = 8192; 63 // there will be a slider for this in the future 64 const float master_gain = 1.0; 65 66 unsigned bs = block_size; 67 68 // stupidity countermeasure... 69 template<class T> T pop_back(std::list<T> &l) { T result(l.back()); l.pop_back(); return result; } 70 71 // a pool, where the DSP can throw its objects at after it got deleted and get them back when it is recreated... 72 class object_pool { 73 public: 74 typedef void* (*callback)(); 75 typedef std::map< void* , void* > map_t; 76 typedef map_t::iterator mapiterator; 77 // initialize 78 object_pool(callback cbf):construct(cbf) { } 79 ~object_pool() { 80 for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();i!=e;i++) 81 //for (mapiterator i=pool.begin(),e=pool.end();i!=e;i++) 82 delete i->second; 83 for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();i!=e;i++) 84 delete *i; 85 } 86 // (re)acquire an object 87 void *acquire(void *who) { 88 std::map<void*,void*>::iterator i(pool.find(who)); 89 if (i != pool.end()) 90 return i->second; 91 else 92 if (!freelist.empty()) 93 return pool.insert(std::make_pair(who,pop_back(freelist))).first->second; 94 else 95 return pool.insert(std::make_pair(who,construct())).first->second; 96 } 97 // release an object into the wild 98 void release(void *who) { 99 std::map<void*,void*>::iterator i(pool.find(who)); 100 if (i != pool.end()) { 101 freelist.push_back(i->second); 102 pool.erase(i); 103 } 104 } 105 public: 106 callback construct; // object constructor callback 107 std::list<void*> freelist; // list of available objects 108 std::map<void*,void*> pool; // pool of used objects, by class 109 }; 110 111 // buffers which we usually need (and want to share between plugin lifespans) 112 struct buffers { 113 buffers(unsigned int s): 114 //block(),result(s), 115 lt(s),rt(s), 116 l(s),r(s),c(s),ls(s),rs(s),lfe(s),cs(s),lcs(s),rcs(s) { } 117 void resize(unsigned int s) { 118 lt.resize(s); rt.resize(s); l.resize(s); r.resize(s); lfe.resize(s); 119 ls.resize(s); rs.resize(s); c.resize(s); cs.resize(s); lcs.resize(s); rcs.resize(s); 120 } 121 void clear() { 122 lt.clear(); rt.clear(); l.clear(); r.clear(); 123 ls.clear(); rs.clear(); c.clear(); 124 //block.clear(); result.clear(); 125 } 126 //std::vector<short> block,result; // for buffering 127 std::vector<float> lt,rt; // for multiplexing 128 std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs; // for demultiplexing 129 }; 130 131 // construction methods 132 void *new_decoder() { return new fsurround_decoder(block_size); } 133 void *new_buffers() { return new buffers(bs); } 134 135 object_pool dp(&new_decoder); 136 object_pool bp(&new_buffers); 137 138 //#define SPEAKERTEST 139 #ifdef SPEAKERTEST 140 int channel_select = -1; 141 #endif 142 143 FreeSurround::FreeSurround(uint srate, bool moviemode) : 144 srate(srate), 145 open_(false), 146 initialized_(false), 147 bufs((buffers*)bp.acquire(this)), 148 decoder(0), 149 in_count(0), 150 out_count(0), 151 processed(true) 152 { 153 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 154 if (moviemode) 155 { 156 params.phasemode = 1; 157 params.center_width = 0; 158 } 159 open(); 160 #ifdef SPEAKERTEST 161 channel_select++; 162 if (channel_select>=6) 163 channel_select = 0; 164 VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select)); 165 #endif 166 167 VERBOSE(QString("FreeSurround::FreeSurround done")); 168 } 169 170 FreeSurround::fsurround_params::fsurround_params( 171 int32_t center_width, 172 int32_t dimension 173 ) : 174 center_width(center_width), 175 dimension(dimension), 176 coeff_a(0.8165),coeff_b(0.5774), 177 phasemode(0), 178 steering(1), 179 front_sep(100), 180 rear_sep(100) 181 { 182 } 183 184 FreeSurround::~FreeSurround() 185 { 186 VERBOSE(QString("FreeSurround::~FreeSurround")); 187 close(); 188 bp.release(this); 189 VERBOSE(QString("FreeSurround::~FreeSurround done")); 190 } 191 192 uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step) 193 { 194 int i; 195 int ic = in_count; 196 int bs = block_size; 197 bool process = true; 198 // demultiplex 199 switch (numChannels) 200 { 201 case 1: 202 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 203 { 204 bufs->lt[ic] = 205 bufs->rt[ic] = 206 samples[i]*master_gain; 207 } 208 break; 209 case 2: 210 if (step>0) 211 { 212 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 213 { 214 bufs->lt[ic] = samples[i]*master_gain; 215 bufs->rt[ic] = samples[i+step]*master_gain; 216 } 217 } 218 else 219 { 220 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 221 { 222 bufs->lt[ic] = samples[i*2]*master_gain; 223 bufs->rt[ic] = samples[i*2+1]*master_gain; 224 } 225 } 226 break; 227 case 6: 228 process = false; 229 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 230 { 231 bufs->l[ic] = *samples++; 232 bufs->c[ic] = *samples++; 233 bufs->r[ic] = *samples++; 234 bufs->ls[ic] = *samples++; 235 bufs->rs[ic] = *samples++; 236 bufs->lfe[ic] = *samples++; 237 } 238 break; 239 } 240 in_count = ic; 241 processed = process; 242 if (ic == bs) 243 { 244 in_count = 0; 245 if (process) 246 process_block(); 247 out_count = bs; 248 } 249 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 250 .arg(numSamples) 251 .arg(numChannels) 252 .arg(step) 253 .arg(i) 254 .arg(out_count) 255 ); 256 return i; 257 } 258 259 uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step) 260 { 261 int i; 262 int ic = in_count; 263 int bs = block_size; 264 bool process = true; 265 // demultiplex 266 switch (numChannels) 267 { 268 case 1: 269 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 270 { 271 bufs->lt[ic] = 272 bufs->rt[ic] = 273 samples[i]*master_gain; 274 } 275 break; 276 case 2: 277 if (step>0) 278 { 279 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 280 { 281 bufs->lt[ic] = samples[i]*master_gain; 282 bufs->rt[ic] = samples[i+step]*master_gain; 283 } 284 } 285 else 286 { 287 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 288 { 289 bufs->lt[ic] = samples[i*2]*master_gain; 290 bufs->rt[ic] = samples[i*2+1]*master_gain; 291 } 292 } 293 break; 294 case 6: 295 process = false; 296 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 297 { 298 bufs->l[ic] = *samples++; 299 bufs->c[ic] = *samples++; 300 bufs->r[ic] = *samples++; 301 bufs->ls[ic] = *samples++; 302 bufs->rs[ic] = *samples++; 303 bufs->lfe[ic] = *samples++; 304 } 305 break; 306 } 307 in_count = ic; 308 processed = process; 309 if (ic == bs) 310 { 311 in_count = 0; 312 if (process) 313 process_block(); 314 out_count = bs; 315 } 316 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 317 .arg(numSamples) 318 .arg(numChannels) 319 .arg(step) 320 .arg(i) 321 .arg(out_count) 322 ); 323 return i; 324 } 325 326 uint FreeSurround::receiveSamples( 327 short *output, 328 uint maxSamples 329 ) 330 { 331 uint i; 332 uint oc = out_count; 333 if (maxSamples>oc) maxSamples = oc; 334 uint outindex = block_size - oc; 335 for (unsigned int i=0;i<maxSamples;i++) 336 { 337 #ifndef BYPASS 338 #ifdef SPEAKERTEST 339 *output++ = (channel_select==0)?(short)bufs->l[outindex]:0; //L 340 *output++ = (channel_select==1)?(short)bufs->r[outindex]:0; //R 341 *output++ = (channel_select==2)?(short)bufs->c[outindex]:0; //LS 342 *output++ = (channel_select==3)?(short)bufs->c[outindex]:0; //RS 343 *output++ = (channel_select==4)?(short)bufs->c[outindex]:0; //C 344 *output++ = (channel_select==5)?(short)bufs->c[outindex]:0; //LFE 345 #else 346 *output++ = (short)bufs->l[outindex]; 347 *output++ = (short)bufs->r[outindex]; 348 *output++ = (short)bufs->ls[outindex]; 349 *output++ = (short)bufs->rs[outindex]; 350 *output++ = (short)bufs->c[outindex]; 351 *output++ = (short)bufs->lfe[outindex]; 352 #endif 353 #else 354 *output++ = (short)bufs->lt[outindex]; 355 *output++ = (short)bufs->rt[outindex]; 356 *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7); 357 *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7); 358 *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5); 359 *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5); 360 #endif 361 oc--; 362 outindex++; 363 } 364 out_count = oc; 365 VERBOSE1(QString("FreeSurround::receiveSamples %1") 366 .arg(maxSamples) 367 ); 368 return maxSamples; 369 } 370 371 void FreeSurround::process_block() 372 { 373 #ifndef BYPASS 374 // process the data 375 try { 376 float *input[2] = {&bufs->lt[0], &bufs->rt[0]}; 377 float *output[8] = {&bufs->l[0], &bufs->c[0], &bufs->r[0], &bufs->ls[0], &bufs->rs[0], &bufs->lfe[0], &bufs->lcs[0], &bufs->rcs[0]}; 378 if (decoder) { 379 // actually these params need only be set when they change... but it doesn't hurt 380 decoder->steering_mode(params.steering); 381 decoder->phase_mode(params.phasemode); 382 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 383 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 384 // decode the bufs->block 385 decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0); 386 } 387 } catch(...) { 388 //throw(std::runtime_error(std::string("error during processing (unsupported input format?)"))); 389 } 390 #endif 391 } 392 393 long long FreeSurround::getLatency() 394 { 395 // returns in usec 396 return decoder ? ((block_size + in_count)*1000000)/(2*srate) : 0; 397 } 398 399 void FreeSurround::flush() { 400 if (decoder) 401 decoder->flush(); 402 bufs->clear(); 403 } 404 405 // load the lib and initialize the interface 406 void FreeSurround::open() 407 { 408 if (!decoder) { 409 decoder = (fsurround_decoder*)dp.acquire(this); 410 decoder->flush(); 411 bufs->clear(); 412 } 413 } 414 415 void FreeSurround::close() 416 { 417 if (decoder) { 418 dp.release(this); 419 decoder = 0; 420 } 421 } 422 423 uint FreeSurround::numUnprocessedSamples() 424 { 425 return in_count; 426 } 427 428 uint FreeSurround::numSamples() 429 { 430 return out_count; 431 } 432 433 uint FreeSurround::sampleLatency() 434 { 435 if (processed) 436 return in_count + out_count + (block_size/2); 437 else 438 return in_count + out_count; 439 } 440 -
libs/libmythfreesurround/freesurround.h
1 /* 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 #include <systems.h> 23 24 class FreeSurround 25 { 26 public: 27 FreeSurround(uint srate, bool moviemode); 28 ~FreeSurround(); 29 30 // put samples in buffer, returns number of samples used 31 uint putSamples(short* samples, uint numSamples, uint numChannels, int step); 32 uint putSamples(char* samples, uint numSamples, uint numChannels, int step); 33 // get a number of samples 34 uint receiveSamples(short *output, 35 uint maxSamples 36 ); 37 // flush unprocessed samples 38 void flush(); 39 //void setSampleRate(uint srate); 40 uint numUnprocessedSamples(); 41 uint numSamples(); 42 43 long long getLatency(); 44 uint sampleLatency(); 45 46 protected: 47 void process_block(); 48 void open(); 49 void close(); 50 51 private: 52 53 // the changeable parameters 54 struct fsurround_params { 55 int32_t center_width; // presence of the center channel 56 int32_t dimension; // dimension 57 float coeff_a,coeff_b; // surround mixing coefficients 58 int32_t phasemode; // phase shifting mode 59 int32_t steering; // steering mode (0=simple, 1=linear) 60 int32_t front_sep, rear_sep;// front/rear stereo separation 61 62 // (default) constructor 63 fsurround_params(int32_t center_width=100, int32_t dimension=0); 64 } params; 65 66 // additional settings 67 uint srate; 68 69 // info about the current setup 70 bool open_; // whether a stream is currently open 71 bool initialized_; // whether the thing is intialized 72 struct buffers *bufs; // our buffers 73 class fsurround_decoder *decoder; // the surround decoder 74 int in_count; // amount in lt,rt 75 int out_count; // amount in output bufs 76 bool processed; // whether processing is enabled or not for latency calc 77 78 }; 79 80 #endif 81 -
libs/libmythfreesurround/libmythfreesurround.pro
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); … … 515 695 // NOTE: This function is not threadsafe 516 696 517 697 int afree = audiofree(true); 518 int len = samples * audio_bytes_per_sample;698 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 519 699 520 700 // Check we have enough space to write the data 521 701 if (need_resampler && src_ctx) … … 527 707 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 528 708 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 529 709 .arg(timecode)); 530 531 710 return false; // would overflow 532 711 } 533 712 … … 564 743 565 744 int AudioOutputBase::WaitForFreeSpace(int samples) 566 745 { 567 int len = samples * audio_bytes_per_sample; 746 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 747 int len = samples * abps; 568 748 int afree = audiofree(false); 569 749 570 750 while (len > afree) 571 751 { 572 752 if (blocking) 573 753 { 574 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +754 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 575 755 QString("(need %1, available %2)").arg(len).arg(afree)); 576 756 577 757 // wait for more space … … 580 760 } 581 761 else 582 762 { 583 VERBOSE(VB_IMPORTANT, LOC_ERR + 584 "Audio buffer overflow, audio data lost!"); 585 samples = afree / audio_bytes_per_sample; 586 len = samples * audio_bytes_per_sample; 763 VERBOSE(VB_IMPORTANT, LOC_ERR + 764 QString("Audio buffer overflow, %1 audio samples lost!") 765 .arg(samples-afree / abps)); 766 samples = afree / abps; 767 len = samples * abps; 587 768 if (src_ctx) 588 769 { 589 770 int error = src_reset(src_ctx); … … 608 789 609 790 int afree = audiofree(false); 610 791 611 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 612 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 613 .arg(samples * audio_bytes_per_sample) 614 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 792 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 793 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 794 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6 upmixer %7") 795 .arg(samples) 796 .arg(samples * abps) 797 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 798 .arg(needs_upmix).arg((uint)(void*)upmixer) 799 ); 615 800 616 len = WaitForFreeSpace(samples); 617 618 if (interleaved) 801 if (upmixer && needs_upmix) 619 802 { 620 char *mybuf = (char*)buffer; 621 int bdiff = AUDBUFSIZE - org_waud; 622 if (bdiff < len) 803 int out_samples = 0; 804 int step = (interleaved)?source_audio_channels:1; 805 len = WaitForFreeSpace(samples); // test 806 for(int itemp=0; itemp<samples; ) 623 807 { 624 memcpy(audiobuffer + org_waud, mybuf, bdiff); 625 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 808 if (audio_bytes == 2) 809 itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 810 else 811 itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 812 813 int copy_samples = upmixer->numSamples(); 814 if (copy_samples) 815 { 816 int copy_len = copy_samples * abps; 817 out_samples += copy_samples; 818 if (out_samples > samples) 819 len = WaitForFreeSpace(out_samples); 820 int bdiff = AUDBUFSIZE - org_waud; 821 if (bdiff < copy_len) 822 { 823 int bdiff_samples = bdiff/abps; 824 upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples); 825 upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples)); 826 } 827 else 828 { 829 upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples); 830 } 831 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 832 } 626 833 } 627 else 628 memcpy(audiobuffer + org_waud, mybuf, len); 629 630 org_waud = (org_waud + len) % AUDBUFSIZE; 631 } 632 else 834 if (samples > 0) 835 { 836 len = WaitForFreeSpace(out_samples); 837 } 838 samples = out_samples; 839 } 840 else 633 841 { 634 char **mybuf = (char**)buffer; 635 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 842 len = WaitForFreeSpace(samples); 843 844 if (interleaved) 636 845 { 637 for (int chan = 0; chan < audio_channels; chan++) 846 char *mybuf = (char*)buffer; 847 int bdiff = AUDBUFSIZE - org_waud; 848 if (bdiff < len) 638 849 { 639 audiobuffer[org_waud++] = mybuf[chan][itemp]; 640 if (audio_bits == 16) 641 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 850 memcpy(audiobuffer + org_waud, mybuf, bdiff); 851 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 852 } 853 else 854 memcpy(audiobuffer + org_waud, mybuf, len); 855 856 org_waud = (org_waud + len) % AUDBUFSIZE; 857 } 858 else 859 { 860 char **mybuf = (char**)buffer; 861 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 862 { 863 for (int chan = 0; chan < audio_channels; chan++) 864 { 865 audiobuffer[org_waud++] = mybuf[chan][itemp]; 866 if (audio_bits == 16) 867 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 642 868 643 if (org_waud >= AUDBUFSIZE) 644 org_waud -= AUDBUFSIZE; 869 if (org_waud >= AUDBUFSIZE) 870 org_waud -= AUDBUFSIZE; 871 } 645 872 } 646 873 } 647 874 } 648 875 876 if (samples > 0) 877 { 649 878 if (pSoundStretch) 650 879 { 880 651 881 // does not change the timecode, only the number of samples 652 882 // back to orig pos 653 883 org_waud = waud; 654 884 int bdiff = AUDBUFSIZE - org_waud; 655 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;885 int nSamplesToEnd = bdiff/abps; 656 886 if (bdiff < len) 657 887 { 658 888 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 659 889 org_waud), nSamplesToEnd); 660 890 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 661 (len - bdiff) / a udio_bytes_per_sample);891 (len - bdiff) / abps); 662 892 } 663 893 else 664 894 { 665 895 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 666 org_waud), len / a udio_bytes_per_sample);896 org_waud), len / abps); 667 897 } 668 898 669 int newLen = 0; 670 int nSamples; 671 len = WaitForFreeSpace(pSoundStretch->numSamples() * 672 audio_bytes_per_sample); 673 do 899 if (encoder) 674 900 { 675 int samplesToGet = len/audio_bytes_per_sample; 676 if (samplesToGet > nSamplesToEnd) 901 // pull out a packet's worth and reencode it until we dont have enough 902 // for any more packets 903 soundtouch::SAMPLETYPE* temp_buff = 904 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 905 size_t frameSize = encoder->FrameSize()/abps; 906 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 907 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 908 .arg(frameSize) 909 .arg(encoder->FrameSize()) 910 .arg(pSoundStretch->numSamples()) 911 ); 912 // process the same number of samples as it creates a full encoded buffer 913 // just like before 914 while (pSoundStretch->numSamples() >= frameSize) 677 915 { 678 samplesToGet = nSamplesToEnd; 916 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 917 int amount = encoder->Encode(temp_buff); 918 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 919 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 920 .arg(amount) 921 .arg(got) 922 .arg(pSoundStretch->numSamples()) 923 ); 924 if (amount == 0) 925 continue; 926 //len = WaitForFreeSpace(amount); 927 char * ob = encoder->GetOutBuff(); 928 if (amount >= bdiff) 929 { 930 memcpy(audiobuffer + org_waud, ob, bdiff); 931 ob += bdiff; 932 amount -= bdiff; 933 org_waud = 0; 934 } 935 if (amount > 0) 936 memcpy(audiobuffer + org_waud, ob, amount); 937 bdiff = AUDBUFSIZE - amount; 938 org_waud += amount; 679 939 } 680 681 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 682 (audiobuffer + org_waud), samplesToGet); 683 if (nSamples == nSamplesToEnd) 940 } 941 else 942 { 943 int newLen = 0; 944 int nSamples; 945 len = WaitForFreeSpace(pSoundStretch->numSamples() * 946 audio_bytes_per_sample); 947 do 684 948 { 685 org_waud = 0; 686 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 687 } 688 else 689 { 690 org_waud += nSamples * audio_bytes_per_sample; 691 nSamplesToEnd -= nSamples; 692 } 949 int samplesToGet = len/audio_bytes_per_sample; 950 if (samplesToGet > nSamplesToEnd) 951 { 952 samplesToGet = nSamplesToEnd; 953 } 693 954 694 newLen += nSamples * audio_bytes_per_sample; 695 len -= nSamples * audio_bytes_per_sample; 696 } while (nSamples > 0); 955 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 956 (audiobuffer + org_waud), samplesToGet); 957 if (nSamples == nSamplesToEnd) 958 { 959 org_waud = 0; 960 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 961 } 962 else 963 { 964 org_waud += nSamples * audio_bytes_per_sample; 965 nSamplesToEnd -= nSamples; 966 } 967 968 newLen += nSamples * audio_bytes_per_sample; 969 len -= nSamples * audio_bytes_per_sample; 970 } while (nSamples > 0); 971 } 697 972 } 698 973 699 974 waud = org_waud; … … 715 990 716 991 if (interleaved) 717 992 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits); 993 } 718 994 719 995 pthread_mutex_unlock(&audio_buflock); 720 996 } … … 769 1045 space_on_soundcard = getSpaceOnSoundcard(); 770 1046 771 1047 if (space_on_soundcard != last_space_on_soundcard) { 772 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1048 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 773 1049 .arg(space_on_soundcard)); 774 1050 last_space_on_soundcard = space_on_soundcard; 775 1051 } … … 782 1058 WriteAudio(zeros, fragment_size); 783 1059 } else { 784 1060 // this should never happen now -dag 785 VERBOSE(VB_AUDIO , LOC +1061 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 786 1062 QString("waiting for space on soundcard " 787 1063 "to write zeros: have %1 need %2") 788 1064 .arg(space_on_soundcard).arg(fragment_size)); … … 818 1094 if (fragment_size > audiolen(true)) 819 1095 { 820 1096 if (audiolen(true) > 0) // only log if we're sending some audio 821 VERBOSE(VB_AUDIO , LOC +1097 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1098 QString("audio waiting for buffer to fill: " 823 1099 "have %1 want %2") 824 1100 .arg(audiolen(true)).arg(fragment_size)); 825 1101 826 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1102 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 827 1103 pthread_mutex_lock(&audio_buflock); 828 1104 pthread_cond_broadcast(&audio_bufsig); 829 1105 pthread_mutex_unlock(&audio_buflock); … … 837 1113 if (fragment_size > space_on_soundcard) 838 1114 { 839 1115 if (space_on_soundcard != last_space_on_soundcard) { 840 VERBOSE(VB_AUDIO , LOC +1116 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 841 1117 QString("audio waiting for space on soundcard: " 842 1118 "have %1 need %2") 843 1119 .arg(space_on_soundcard).arg(fragment_size)); … … 899 1175 900 1176 /* update raud */ 901 1177 raud = (raud + fragment_size) % AUDBUFSIZE; 902 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1178 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 903 1179 pthread_cond_broadcast(&audio_bufsig); 904 1180 905 1181 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:analog", "ALSA:analog"); 61 gc->addSelection("ALSA:digital", "ALSA:digital"); 62 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 63 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 60 64 #endif 61 65 #ifdef USING_ARTS 62 66 gc->addSelection("ARTS:", "ARTS:"); … … 78 82 return gc; 79 83 } 80 84 85 static HostComboBox *MaxAudioChannels() 86 { 87 HostComboBox *gc = new HostComboBox("MaxChannels",false); 88 gc->setLabel(QObject::tr("Max Audio Channels")); 89 //gc->addSelection(QObject::tr("Mono"), "1"); 90 //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 91 //gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 92 //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 93 //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 94 //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 95 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 96 gc->addSelection(QObject::tr("6 Channel"), "6"); 97 gc->setHelpText( 98 QObject::tr("Set the maximum number of audio channels to be decoded. " 99 "This is for multi-channel/surround audio playback.")); 100 return gc; 101 } 102 81 103 static HostComboBox *PassThroughOutputDevice() 82 104 { 83 105 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3143 3165 new VerticalConfigurationGroup(false, false, true, true); 3144 3166 vgrp0->addChild(AC3PassThrough()); 3145 3167 vgrp0->addChild(DTSPassThrough()); 3168 addChild(MaxAudioChannels()); 3146 3169 3147 3170 VerticalConfigurationGroup *vgrp1 = 3148 3171 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;