Ticket #1104: mythtv_ac3.36.patch
File mythtv_ac3.36.patch, 107.7 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/4;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) 72 { 73 T result(l.back()); 74 l.pop_back(); 75 return result; 76 } 77 78 // a pool, where the DSP can throw its objects at after it got deleted and get them back when it is recreated... 79 class object_pool 80 { 81 public: 82 typedef void* (*callback)(); 83 // initialize 84 object_pool(callback cbf):construct(cbf) { } 85 ~object_pool() 86 { 87 for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();i!=e;i++) 88 delete i->second; 89 for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();i!=e;i++) 90 delete *i; 91 } 92 // (re)acquire an object 93 void *acquire(void *who) 94 { 95 std::map<void*,void*>::iterator i(pool.find(who)); 96 if (i != pool.end()) 97 return i->second; 98 else 99 if (!freelist.empty()) 100 return pool.insert(std::make_pair(who,pop_back(freelist))).first->second; 101 else 102 return pool.insert(std::make_pair(who,construct())).first->second; 103 } 104 // release an object into the wild 105 void release(void *who) 106 { 107 std::map<void*,void*>::iterator i(pool.find(who)); 108 if (i != pool.end()) { 109 freelist.push_back(i->second); 110 pool.erase(i); 111 } 112 } 113 public: 114 callback construct; // object constructor callback 115 std::list<void*> freelist; // list of available objects 116 std::map<void*,void*> pool; // pool of used objects, by class 117 }; 118 119 // buffers which we usually need (and want to share between plugin lifespans) 120 struct buffers 121 { 122 buffers(unsigned int s): 123 //block(),result(s), 124 lt(s),rt(s), 125 l(s),r(s),c(s),ls(s),rs(s),lfe(s),cs(s),lcs(s),rcs(s) { } 126 void resize(unsigned int s) 127 { 128 lt.resize(s); rt.resize(s); l.resize(s); r.resize(s); lfe.resize(s); 129 ls.resize(s); rs.resize(s); c.resize(s); cs.resize(s); lcs.resize(s); rcs.resize(s); 130 } 131 void clear() 132 { 133 lt.clear(); rt.clear(); l.clear(); r.clear(); 134 ls.clear(); rs.clear(); c.clear(); 135 //block.clear(); result.clear(); 136 } 137 std::vector<float> lt,rt; // for multiplexing 138 std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs; // for demultiplexing 139 }; 140 141 // construction methods 142 void *new_decoder() { return new fsurround_decoder(block_size); } 143 void *new_buffers() { return new buffers(bs); } 144 145 object_pool dp(&new_decoder); 146 object_pool bp(&new_buffers); 147 148 //#define SPEAKERTEST 149 #ifdef SPEAKERTEST 150 int channel_select = -1; 151 #endif 152 153 FreeSurround::FreeSurround(uint srate, bool moviemode) : 154 srate(srate), 155 open_(false), 156 initialized_(false), 157 bufs((buffers*)bp.acquire(this)), 158 decoder(0), 159 in_count(0), 160 out_count(0), 161 processed(true) 162 { 163 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 164 if (moviemode) 165 { 166 params.phasemode = 1; 167 params.center_width = 0; 168 //params.steering = 0; 169 } 170 else 171 { 172 params.center_width = 50; 173 } 174 open(); 175 #ifdef SPEAKERTEST 176 channel_select++; 177 if (channel_select>=6) 178 channel_select = 0; 179 VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select)); 180 #endif 181 182 VERBOSE(QString("FreeSurround::FreeSurround done")); 183 } 184 185 FreeSurround::fsurround_params::fsurround_params( 186 int32_t center_width, 187 int32_t dimension 188 ) : 189 center_width(center_width), 190 dimension(dimension), 191 coeff_a(0.8165),coeff_b(0.5774), 192 phasemode(0), 193 steering(1), 194 front_sep(100), 195 rear_sep(100) 196 { 197 } 198 199 FreeSurround::~FreeSurround() 200 { 201 VERBOSE(QString("FreeSurround::~FreeSurround")); 202 close(); 203 bp.release(this); 204 VERBOSE(QString("FreeSurround::~FreeSurround done")); 205 } 206 207 uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step) 208 { 209 int i; 210 int ic = in_count; 211 int bs = block_size; 212 bool process = true; 213 // demultiplex 214 switch (numChannels) 215 { 216 case 1: 217 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 218 { 219 bufs->lt[ic] = 220 bufs->rt[ic] = 221 samples[i] * master_gain; 222 } 223 break; 224 case 2: 225 if (step>0) 226 { 227 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 228 { 229 bufs->lt[ic] = samples[i] * master_gain; 230 bufs->rt[ic] = samples[i+step] * master_gain; 231 } 232 } 233 else 234 { 235 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 236 { 237 bufs->lt[ic] = samples[i*2] * master_gain; 238 bufs->rt[ic] = samples[i*2+1] * master_gain; 239 } 240 } 241 break; 242 case 6: 243 process = false; 244 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 245 { 246 bufs->l[ic] = *samples++ * master_gain; 247 bufs->c[ic] = *samples++ * master_gain; 248 bufs->r[ic] = *samples++ * master_gain; 249 bufs->ls[ic] = *samples++ * master_gain; 250 bufs->rs[ic] = *samples++ * master_gain; 251 bufs->lfe[ic] = *samples++ * master_gain; 252 } 253 break; 254 } 255 in_count = ic; 256 processed = process; 257 if (ic == bs) 258 { 259 in_count = 0; 260 if (process) 261 process_block(); 262 out_count = bs; 263 } 264 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 265 .arg(numSamples) 266 .arg(numChannels) 267 .arg(step) 268 .arg(i) 269 .arg(out_count) 270 ); 271 return i; 272 } 273 274 uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step) 275 { 276 int i; 277 int ic = in_count; 278 int bs = block_size; 279 bool process = true; 280 // demultiplex 281 switch (numChannels) 282 { 283 case 1: 284 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 285 { 286 bufs->lt[ic] = 287 bufs->rt[ic] = 288 samples[i] * master_gain; 289 } 290 break; 291 case 2: 292 if (step>0) 293 { 294 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 295 { 296 bufs->lt[ic] = samples[i] * master_gain; 297 bufs->rt[ic] = samples[i+step] * master_gain; 298 } 299 } 300 else 301 { 302 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 303 { 304 bufs->lt[ic] = samples[i*2] * master_gain; 305 bufs->rt[ic] = samples[i*2+1] * master_gain; 306 } 307 } 308 break; 309 case 6: 310 process = false; 311 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 312 { 313 bufs->l[ic] = *samples++ * master_gain; 314 bufs->c[ic] = *samples++ * master_gain; 315 bufs->r[ic] = *samples++ * master_gain; 316 bufs->ls[ic] = *samples++ * master_gain; 317 bufs->rs[ic] = *samples++ * master_gain; 318 bufs->lfe[ic] = *samples++ * master_gain; 319 } 320 break; 321 } 322 in_count = ic; 323 processed = process; 324 if (ic == bs) 325 { 326 in_count = 0; 327 if (process) 328 process_block(); 329 out_count = bs; 330 } 331 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 332 .arg(numSamples) 333 .arg(numChannels) 334 .arg(step) 335 .arg(i) 336 .arg(out_count) 337 ); 338 return i; 339 } 340 341 uint FreeSurround::receiveSamples( 342 short *output, 343 uint maxSamples 344 ) 345 { 346 uint i; 347 uint oc = out_count; 348 if (maxSamples>oc) maxSamples = oc; 349 uint outindex = block_size - oc; 350 for (unsigned int i=0;i<maxSamples;i++) 351 { 352 #ifndef BYPASS 353 #ifdef SPEAKERTEST 354 *output++ = (channel_select==0)?(short)bufs->l[outindex]:0; //L 355 *output++ = (channel_select==1)?(short)bufs->r[outindex]:0; //R 356 *output++ = (channel_select==2)?(short)bufs->c[outindex]:0; //LS 357 *output++ = (channel_select==3)?(short)bufs->c[outindex]:0; //RS 358 *output++ = (channel_select==4)?(short)bufs->c[outindex]:0; //C 359 *output++ = (channel_select==5)?(short)bufs->c[outindex]:0; //LFE 360 #else 361 *output++ = lrintf(bufs->l[outindex] * inv_master_gain); 362 *output++ = lrintf(bufs->r[outindex] * inv_master_gain); 363 *output++ = lrintf(bufs->ls[outindex] * inv_master_gain); 364 *output++ = lrintf(bufs->rs[outindex] * inv_master_gain); 365 *output++ = lrintf(bufs->c[outindex] * inv_master_gain); 366 *output++ = lrintf(bufs->lfe[outindex] * inv_master_gain); 367 #endif 368 #else 369 *output++ = (short)bufs->lt[outindex]; 370 *output++ = (short)bufs->rt[outindex]; 371 *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7); 372 *output++ = (short)((bufs->lt[outindex] - bufs->rt[outindex])*0.7); 373 *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5); 374 *output++ = (short)((bufs->lt[outindex] + bufs->rt[outindex])*0.5); 375 #endif 376 oc--; 377 outindex++; 378 } 379 out_count = oc; 380 VERBOSE1(QString("FreeSurround::receiveSamples %1") 381 .arg(maxSamples) 382 ); 383 return maxSamples; 384 } 385 386 void FreeSurround::process_block() 387 { 388 #ifndef BYPASS 389 // process the data 390 try 391 { 392 float *input[2] = {&bufs->lt[0], &bufs->rt[0]}; 393 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]}; 394 if (decoder) 395 { 396 // actually these params need only be set when they change... but it doesn't hurt 397 decoder->steering_mode(params.steering); 398 decoder->phase_mode(params.phasemode); 399 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 400 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 401 // decode the bufs->block 402 decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0); 403 } 404 } 405 catch(...) 406 { 407 //throw(std::runtime_error(std::string("error during processing (unsupported input format?)"))); 408 } 409 #endif 410 } 411 412 long long FreeSurround::getLatency() 413 { 414 // returns in usec 415 return decoder ? ((block_size + in_count)*1000000)/(2*srate) : 0; 416 } 417 418 void FreeSurround::flush() 419 { 420 if (decoder) 421 decoder->flush(); 422 bufs->clear(); 423 } 424 425 // load the lib and initialize the interface 426 void FreeSurround::open() 427 { 428 if (!decoder) 429 { 430 decoder = (fsurround_decoder*)dp.acquire(this); 431 decoder->flush(); 432 bufs->clear(); 433 } 434 } 435 436 void FreeSurround::close() 437 { 438 if (decoder) 439 { 440 dp.release(this); 441 decoder = 0; 442 } 443 } 444 445 uint FreeSurround::numUnprocessedSamples() 446 { 447 return in_count; 448 } 449 450 uint FreeSurround::numSamples() 451 { 452 return out_count; 453 } 454 455 uint FreeSurround::sampleLatency() 456 { 457 if (processed) 458 return in_count + out_count + (block_size/2); 459 else 460 return in_count + out_count; 461 } 462 463 uint FreeSurround::samplesPerBlock() 464 { 465 return block_size; 466 } 467 -
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 uint samplesPerBlock(); 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 #define UPMIXINLOOP 0 21 22 namespace soundtouch { 23 class SoundTouch; 24 }; 25 class FreeSurround; 26 class AudioOutputDigitalEncoder; 27 struct AVCodecContext; 28 22 29 #define AUDIO_SRC_IN_SIZE 16384 23 30 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 31 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 32 33 //#define AUDBUFSIZE 768000 34 //divisible by 12,10,8,6,4,2 and around 1024000 35 //#define AUDBUFSIZE 1024080 36 #define AUDBUFSIZE 1536000 37 26 38 class AudioOutputBase : public AudioOutput 27 39 { 28 40 public: … … 35 47 virtual ~AudioOutputBase(); 36 48 37 49 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 50 virtual void Reconfigure(int audio_bits, 51 int audio_channels, 52 int audio_samplerate, 53 bool audio_passthru, 54 void* audio_codec = NULL); 40 55 41 56 // do AddSamples calls block? 42 57 virtual void SetBlocking(bool blocking); … … 94 109 void OutputAudioLoop(void); 95 110 static void *kickoffOutputAudioLoop(void *player); 96 111 void SetAudiotime(void); 97 int WaitForFreeSpace(int len );112 int WaitForFreeSpace(int len, bool wait_min); 98 113 99 114 int audiolen(bool use_lock); // number of valid bytes in audio buffer 100 115 int audiofree(bool use_lock); // number of free bytes in audio buffer … … 125 140 bool audio_passthru; 126 141 127 142 float audio_stretchfactor; 143 AVCodecContext *audio_codec; 128 144 AudioOutputSource source; 129 145 130 146 bool killaudio; … … 133 149 bool set_initial_vol; 134 150 bool buffer_output_data_for_use; // used by AudioOutputNULL 135 151 152 int configured_audio_channels; 153 136 154 private: 137 155 // resampler 138 156 bool need_resampler; … … 144 162 145 163 // timestretch 146 164 soundtouch::SoundTouch * pSoundStretch; 165 AudioOutputDigitalEncoder * encoder; 166 FreeSurround * upmixer; 147 167 168 #if !UPMIXINLOOP 169 int source_audio_channels; 170 int source_audio_bytes_per_sample; 171 #endif 172 bool needs_upmix; 173 148 174 bool blocking; // do AddSamples calls block? 149 175 150 176 int lastaudiolen; … … 162 188 163 189 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 164 190 'audiotime' and 'audiotime_updated' */ 165 intaudiotime; // timecode of audio leaving the soundcard (same units as191 long long audiotime; // timecode of audio leaving the soundcard (same units as 166 192 // timecodes) ... 167 193 struct timeval audiotime_updated; // ... which was last updated at this time 168 194 169 195 /* Audio circular buffer */ 170 196 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 171 197 int raud, waud; /* read and write positions */ 172 intaudbuf_timecode; /* timecode of audio most recently placed into198 long long audbuf_timecode; /* timecode of audio most recently placed into 173 199 buffer */ 174 200 175 201 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 #if !UPMIXINLOOP 58 source_audio_channels(-1), 59 source_audio_bytes_per_sample(0), 60 #endif 61 needs_upmix(false), 51 62 63 blocking(false), 64 52 65 lastaudiolen(0), samples_buffered(0), 53 66 54 67 audio_thread_exists(false), … … 71 84 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 85 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 86 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 87 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 88 75 89 // You need to call Reconfigure from your concrete class. 76 90 // Reconfigure(laudio_bits, laudio_channels, … … 111 125 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 126 .arg(audio_stretchfactor)); 113 127 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 128 if (audio_codec) 129 { 130 if (!encoder) 131 { 132 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 133 encoder = new AudioOutputDigitalEncoder(); 134 if (!encoder->Init(audio_codec->codec_id, 135 audio_codec->bit_rate, 136 audio_codec->sample_rate, 137 audio_codec->channels 138 )) 139 { 140 // eeks 141 delete encoder; 142 encoder = NULL; 143 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 144 } 145 } 146 } 147 if (encoder) 148 { 149 pSoundStretch->setSampleRate(audio_codec->sample_rate); 150 pSoundStretch->setChannels(audio_codec->channels); 151 } 152 else 153 { 154 pSoundStretch->setSampleRate(audio_samplerate); 155 pSoundStretch->setChannels(audio_channels); 156 } 116 157 117 158 pSoundStretch->setTempo(audio_stretchfactor); 118 159 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 135 176 } 136 177 137 178 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 179 int laudio_samplerate, bool laudio_passthru, 180 void* laudio_codec) 139 181 { 182 int codec_id = CODEC_ID_NONE; 183 int lcodec_id = CODEC_ID_NONE; 184 int lcchannels = 0; 185 int cchannels = 0; 186 int lsource_audio_channels = laudio_channels; 187 bool lneeds_upmix = false; 188 189 if (laudio_codec) 190 { 191 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 192 laudio_bits = 16; 193 laudio_channels = 2; 194 lsource_audio_channels = laudio_channels; 195 laudio_samplerate = 48000; 196 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 197 } 198 if (audio_codec) 199 { 200 codec_id = audio_codec->codec_id; 201 cchannels = ((AVCodecContext*)audio_codec)->channels; 202 } 203 if ((configured_audio_channels == 6) && 204 !(laudio_codec || audio_codec)) 205 { 206 #if !UPMIXINLOOP 207 laudio_channels = configured_audio_channels; 208 #endif 209 lneeds_upmix = true; 210 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 211 } 212 ClearError(); 140 213 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 214 laudio_samplerate == audio_samplerate && !need_resampler && 215 laudio_passthru == audio_passthru && 216 lneeds_upmix == needs_upmix && 217 lcodec_id == codec_id && lcchannels == cchannels) 218 { 219 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 220 return; 144 221 } 145 222 KillAudio(); 146 223 147 224 pthread_mutex_lock(&audio_buflock); … … 151 228 waud = raud = 0; 152 229 audio_actually_paused = false; 153 230 231 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 232 audio_channels = laudio_channels; 233 #if !UPMIXINLOOP 234 source_audio_channels = lsource_audio_channels; 235 #endif 155 236 audio_bits = laudio_bits; 156 237 audio_samplerate = laudio_samplerate; 238 audio_codec = (AVCodecContext*)laudio_codec; 157 239 audio_passthru = laudio_passthru; 240 needs_upmix = lneeds_upmix; 158 241 if (audio_bits != 8 && audio_bits != 16) 159 242 { 160 243 pthread_mutex_unlock(&avsync_lock); … … 163 246 return; 164 247 } 165 248 audio_bytes_per_sample = audio_channels * audio_bits / 8; 249 #if !UPMIXINLOOP 250 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 251 #endif 166 252 167 253 need_resampler = false; 168 254 killaudio = false; … … 172 258 173 259 numlowbuffer = 0; 174 260 261 #if UPMIXINLOOP 262 int fake_channels = audio_channels; 263 audio_channels = configured_audio_channels; 264 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 265 .arg(audio_main_device).arg(configured_audio_channels) 266 .arg(audio_channels).arg(audio_samplerate)); 267 175 268 // Actually do the device specific open call 269 bool openresult = OpenDevice(); 270 audio_channels = fake_channels; 271 if (!openresult) 272 #else 273 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 274 .arg(audio_main_device).arg(audio_channels) 275 .arg(source_audio_channels).arg(audio_samplerate)); 276 277 // Actually do the device specific open call 176 278 if (!OpenDevice()) 279 #endif 177 280 { 178 281 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 282 pthread_mutex_unlock(&avsync_lock); 180 283 pthread_mutex_unlock(&audio_buflock); 284 if (GetError().isEmpty()) 285 Error("Aborting reconfigure"); 286 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 287 return; 182 288 } 183 289 … … 200 306 current_seconds = -1; 201 307 source_bitrate = -1; 202 308 309 // NOTE: this wont do anything as above samplerate vars are set equal 203 310 // Check if we need the resampler 204 311 if (audio_samplerate != laudio_samplerate) 205 312 { … … 222 329 need_resampler = true; 223 330 } 224 331 332 if (needs_upmix) 333 { 334 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 335 upmixer = new FreeSurround(audio_samplerate, source == AUDIOOUTPUT_VIDEO); 336 VERBOSE(VB_AUDIO, LOC + QString("create upmixer done")); 337 } 338 225 339 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 340 .arg(audio_stretchfactor)); 341 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 342 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 227 343 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 344 if (redo_stretch) 230 345 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 346 float laudio_stretchfactor = audio_stretchfactor; 347 delete pSoundStretch; 348 pSoundStretch = NULL; 349 audio_stretchfactor = 0.0; 350 SetStretchFactorLocked(laudio_stretchfactor); 233 351 } 352 else 353 { 354 SetStretchFactorLocked(audio_stretchfactor); 355 if (pSoundStretch) 356 { 357 // if its passthru then we need to reencode 358 if (audio_codec) 359 { 360 if (!encoder) 361 { 362 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 363 encoder = new AudioOutputDigitalEncoder(); 364 if (!encoder->Init(audio_codec->codec_id, 365 audio_codec->bit_rate, 366 audio_codec->sample_rate, 367 audio_codec->channels 368 )) 369 { 370 // eeks 371 delete encoder; 372 encoder = NULL; 373 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 374 } 375 } 376 } 377 if (encoder) 378 { 379 pSoundStretch->setSampleRate(audio_codec->sample_rate); 380 pSoundStretch->setChannels(audio_codec->channels); 381 } 382 else 383 { 384 pSoundStretch->setSampleRate(audio_samplerate); 385 pSoundStretch->setChannels(audio_channels); 386 } 387 } 388 } 234 389 235 390 // Setup visualisations, zero the visualisations buffers 236 391 prepareVisuals(); … … 290 445 pSoundStretch = NULL; 291 446 } 292 447 448 if (encoder) 449 { 450 delete encoder; 451 encoder = NULL; 452 } 453 454 if (upmixer) 455 { 456 delete upmixer; 457 upmixer = NULL; 458 } 459 needs_upmix = false; 460 293 461 CloseDevice(); 294 462 295 463 killAudioLock.unlock(); … … 303 471 304 472 void AudioOutputBase::Pause(bool paused) 305 473 { 474 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 306 475 pauseaudio = paused; 307 476 audio_actually_paused = false; 308 477 } … … 385 554 The reason is that computing 'audiotime' requires acquiring the audio 386 555 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 556 from the audio thread, and then call this from the video thread. */ 388 intret;557 long long ret; 389 558 struct timeval now; 390 559 391 560 if (audiotime == 0) … … 397 566 398 567 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 568 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);569 ret = (long long)(ret * audio_stretchfactor); 401 570 571 #if 1 572 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 573 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 574 .arg(now.tv_sec).arg(now.tv_usec) 575 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 576 .arg(ret) 577 .arg(audiotime) 578 .arg(audio_stretchfactor) 579 ); 580 #endif 581 402 582 ret += audiotime; 403 583 404 584 pthread_mutex_unlock(&avsync_lock); 405 return ret;585 return (int)ret; 406 586 } 407 587 408 588 void AudioOutputBase::SetAudiotime(void) … … 439 619 // include algorithmic latencies 440 620 if (pSoundStretch) 441 621 { 622 // add the effect of any unused but processed samples, AC3 reencode does this 623 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 442 624 // add the effect of unprocessed samples in time stretch algo 443 625 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 626 audio_bytes_per_sample) / audio_stretchfactor); 445 627 } 446 628 629 #if !UPMIXINLOOP 630 if (upmixer && needs_upmix) 631 { 632 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 633 } 634 #endif 635 447 636 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 637 (audio_bytes_per_sample * effdspstretched)); 449 638 450 639 gettimeofday(&audiotime_updated, NULL); 640 #if 1 641 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 642 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 643 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 644 .arg(audiotime) 645 .arg(audbuf_timecode) 646 .arg(totalbuffer) 647 .arg(soundcard_buffer) 648 .arg(effdspstretched) 649 .arg(audio_bytes_per_sample) 650 .arg(audio_stretchfactor) 651 ); 652 #endif 451 653 452 654 pthread_mutex_unlock(&avsync_lock); 453 655 pthread_mutex_unlock(&audio_buflock); … … 464 666 if (need_resampler && src_ctx) 465 667 len = (int)ceilf(float(len) * src_data.src_ratio); 466 668 669 #if !UPMIXINLOOP 670 // include samples in upmix buffer that may be flushed 671 if (needs_upmix && upmixer) 672 len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample; 673 #endif 674 467 675 if ((len > afree) && !blocking) 468 676 { 469 677 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( … … 515 723 // NOTE: This function is not threadsafe 516 724 517 725 int afree = audiofree(true); 518 int len = samples * audio_bytes_per_sample;726 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 519 727 520 728 // Check we have enough space to write the data 521 729 if (need_resampler && src_ctx) 522 730 len = (int)ceilf(float(len) * src_data.src_ratio); 523 731 732 #if !UPMIXINLOOP 733 // include samples in upmix buffer that may be flushed 734 if (needs_upmix && upmixer) 735 len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample; 736 #endif 737 524 738 if ((len > afree) && !blocking) 525 739 { 526 740 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( 527 741 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 528 742 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 529 743 .arg(timecode)); 530 531 744 return false; // would overflow 532 745 } 533 746 … … 562 775 return true; 563 776 } 564 777 565 int AudioOutputBase::WaitForFreeSpace(int samples )778 int AudioOutputBase::WaitForFreeSpace(int samples, bool wait_min) 566 779 { 567 int len = samples * audio_bytes_per_sample; 780 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 781 int len = samples * abps; 568 782 int afree = audiofree(false); 569 783 570 784 while (len > afree) 571 785 { 572 786 if (blocking) 573 787 { 574 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +788 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 575 789 QString("(need %1, available %2)").arg(len).arg(afree)); 576 790 577 791 // wait for more space … … 580 794 } 581 795 else 582 796 { 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; 797 if (wait_min) 798 { 799 int time_to_wait = ((len-afree)*1000000)/(audio_samplerate*abps); 800 pthread_mutex_unlock(&audio_buflock); 801 usleep(time_to_wait + 5000); // 5ms extra to allow for output loop 802 pthread_mutex_lock(&audio_buflock); 803 afree = audiofree(false); 804 wait_min = false; // do it once only 805 continue; 806 } 807 VERBOSE(VB_IMPORTANT, LOC_ERR + 808 QString("Audio buffer overflow, %1 audio samples lost!") 809 .arg(samples-afree / abps)); 810 samples = afree / abps; 811 len = samples * abps; 587 812 if (src_ctx) 588 813 { 589 814 int error = src_reset(src_ctx); … … 608 833 609 834 int afree = audiofree(false); 610 835 611 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 612 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 613 .arg(samples * audio_bytes_per_sample) 614 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 836 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 837 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 838 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6 upmixer %7") 839 .arg(samples) 840 .arg(samples * abps) 841 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 842 .arg(needs_upmix).arg((uint)(void*)upmixer) 843 ); 615 844 616 len = WaitForFreeSpace(samples); 617 618 if (interleaved) 845 #if !UPMIXINLOOP 846 if (upmixer && needs_upmix) 619 847 { 620 char *mybuf = (char*)buffer; 621 int bdiff = AUDBUFSIZE - org_waud; 622 if (bdiff < len) 848 int out_samples = 0; 849 int step = (interleaved)?source_audio_channels:1; 850 len = WaitForFreeSpace(samples, true); // test 851 for(int itemp=0; itemp<samples; ) 623 852 { 624 memcpy(audiobuffer + org_waud, mybuf, bdiff); 625 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 853 // just in case it does a processing cycle, release the lock 854 // to allow the output loop to do output 855 pthread_mutex_unlock(&audio_buflock); 856 if (audio_bytes == 2) 857 itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 858 else 859 itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 860 pthread_mutex_lock(&audio_buflock); 861 862 int copy_samples = upmixer->numSamples(); 863 if (copy_samples) 864 { 865 int copy_len = copy_samples * abps; 866 out_samples += copy_samples; 867 if (out_samples > samples) 868 len = WaitForFreeSpace(out_samples, true); 869 int bdiff = AUDBUFSIZE - org_waud; 870 if (bdiff < copy_len) 871 { 872 int bdiff_samples = bdiff/abps; 873 upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples); 874 upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples)); 875 } 876 else 877 { 878 upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples); 879 } 880 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 881 } 626 882 } 627 else 628 memcpy(audiobuffer + org_waud, mybuf, len); 629 630 org_waud = (org_waud + len) % AUDBUFSIZE; 631 } 632 else 883 if (samples > 0) 884 { 885 len = WaitForFreeSpace(out_samples, true); 886 } 887 samples = out_samples; 888 } 889 else 890 #endif 633 891 { 634 char **mybuf = (char**)buffer; 635 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 892 len = WaitForFreeSpace(samples, true); 893 894 if (interleaved) 636 895 { 637 for (int chan = 0; chan < audio_channels; chan++) 896 char *mybuf = (char*)buffer; 897 int bdiff = AUDBUFSIZE - org_waud; 898 if (bdiff < len) 638 899 { 639 audiobuffer[org_waud++] = mybuf[chan][itemp]; 640 if (audio_bits == 16) 641 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 900 memcpy(audiobuffer + org_waud, mybuf, bdiff); 901 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 902 } 903 else 904 memcpy(audiobuffer + org_waud, mybuf, len); 905 906 org_waud = (org_waud + len) % AUDBUFSIZE; 907 } 908 else 909 { 910 char **mybuf = (char**)buffer; 911 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 912 { 913 for (int chan = 0; chan < audio_channels; chan++) 914 { 915 audiobuffer[org_waud++] = mybuf[chan][itemp]; 916 if (audio_bits == 16) 917 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 642 918 643 if (org_waud >= AUDBUFSIZE) 644 org_waud -= AUDBUFSIZE; 919 if (org_waud >= AUDBUFSIZE) 920 org_waud -= AUDBUFSIZE; 921 } 645 922 } 646 923 } 647 924 } 648 925 649 if (pSoundStretch) 926 #if !UPMIXINLOOP 927 if (samples > 0) 928 #endif 650 929 { 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) 930 if (pSoundStretch) 657 931 { 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 932 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) 933 // does not change the timecode, only the number of samples 934 // back to orig pos 935 org_waud = waud; 936 int bdiff = AUDBUFSIZE - org_waud; 937 int nSamplesToEnd = bdiff/abps; 938 if (bdiff < len) 677 939 { 678 samplesToGet = nSamplesToEnd; 940 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 941 org_waud), nSamplesToEnd); 942 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 943 (len - bdiff) / abps); 679 944 } 945 else 946 { 947 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 948 org_waud), len / abps); 949 } 680 950 681 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 682 (audiobuffer + org_waud), samplesToGet); 683 if (nSamples == nSamplesToEnd) 951 if (encoder) 684 952 { 685 org_waud = 0; 686 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 953 // pull out a packet's worth and reencode it until we dont have enough 954 // for any more packets 955 soundtouch::SAMPLETYPE* temp_buff = 956 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 957 size_t frameSize = encoder->FrameSize()/abps; 958 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 959 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 960 .arg(frameSize) 961 .arg(encoder->FrameSize()) 962 .arg(pSoundStretch->numSamples()) 963 ); 964 // process the same number of samples as it creates a full encoded buffer 965 // just like before 966 while (pSoundStretch->numSamples() >= frameSize) 967 { 968 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 969 int amount = encoder->Encode(temp_buff); 970 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 971 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 972 .arg(amount) 973 .arg(got) 974 .arg(pSoundStretch->numSamples()) 975 ); 976 if (amount == 0) 977 continue; 978 //len = WaitForFreeSpace(amount); 979 char * ob = encoder->GetOutBuff(); 980 if (amount >= bdiff) 981 { 982 memcpy(audiobuffer + org_waud, ob, bdiff); 983 ob += bdiff; 984 amount -= bdiff; 985 org_waud = 0; 986 } 987 if (amount > 0) 988 memcpy(audiobuffer + org_waud, ob, amount); 989 bdiff = AUDBUFSIZE - amount; 990 org_waud += amount; 991 } 687 992 } 688 993 else 689 994 { 690 org_waud += nSamples * audio_bytes_per_sample; 691 nSamplesToEnd -= nSamples; 995 int newLen = 0; 996 int nSamples; 997 len = WaitForFreeSpace(pSoundStretch->numSamples() * 998 audio_bytes_per_sample, true); 999 do 1000 { 1001 int samplesToGet = len/audio_bytes_per_sample; 1002 if (samplesToGet > nSamplesToEnd) 1003 { 1004 samplesToGet = nSamplesToEnd; 1005 } 1006 1007 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1008 (audiobuffer + org_waud), samplesToGet); 1009 if (nSamples == nSamplesToEnd) 1010 { 1011 org_waud = 0; 1012 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1013 } 1014 else 1015 { 1016 org_waud += nSamples * audio_bytes_per_sample; 1017 nSamplesToEnd -= nSamples; 1018 } 1019 1020 newLen += nSamples * audio_bytes_per_sample; 1021 len -= nSamples * audio_bytes_per_sample; 1022 } while (nSamples > 0); 692 1023 } 1024 } 693 1025 694 newLen += nSamples * audio_bytes_per_sample; 695 len -= nSamples * audio_bytes_per_sample; 696 } while (nSamples > 0); 697 } 1026 waud = org_waud; 1027 lastaudiolen = audiolen(false); 698 1028 699 waud = org_waud; 700 lastaudiolen = audiolen(false); 1029 if (timecode < 0) 1030 { 1031 // mythmusic doesn't give timestamps.. 1032 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1033 } 1034 1035 samples_buffered += samples; 1036 1037 /* we want the time at the end -- but the file format stores 1038 time at the start of the chunk. */ 1039 // even with timestretch, timecode is still calculated from original 1040 // sample count 1041 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 701 1042 702 samples_buffered += samples;703 704 if (timecode < 0)705 { 706 // mythmusic doesn't give timestamps..707 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1043 if (interleaved) 1044 #if UPMIXINLOOP 1045 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits); 1046 #else 1047 dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits); 1048 #endif 708 1049 } 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 1050 716 if (interleaved)717 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);718 719 1051 pthread_mutex_unlock(&audio_buflock); 720 1052 } 721 1053 … … 728 1060 729 1061 if (source_bitrate == -1) 730 1062 { 1063 #if UPMIXINLOOP 731 1064 source_bitrate = audio_samplerate * audio_channels * audio_bits; 1065 #else 1066 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 1067 #endif 732 1068 } 733 1069 734 1070 if (ct / 1000 != current_seconds) 735 1071 { 736 1072 current_seconds = ct / 1000; 1073 #if UPMIXINLOOP 737 1074 OutputEvent e(current_seconds, ct, 738 1075 source_bitrate, audio_samplerate, audio_bits, 739 1076 audio_channels); 1077 #else 1078 OutputEvent e(current_seconds, ct, 1079 source_bitrate, audio_samplerate, audio_bits, 1080 source_audio_channels); 1081 #endif 740 1082 dispatch(e); 741 1083 } 742 1084 } … … 769 1111 space_on_soundcard = getSpaceOnSoundcard(); 770 1112 771 1113 if (space_on_soundcard != last_space_on_soundcard) { 772 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1114 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 773 1115 .arg(space_on_soundcard)); 774 1116 last_space_on_soundcard = space_on_soundcard; 775 1117 } … … 782 1124 WriteAudio(zeros, fragment_size); 783 1125 } else { 784 1126 // this should never happen now -dag 785 VERBOSE(VB_AUDIO , LOC +1127 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 786 1128 QString("waiting for space on soundcard " 787 1129 "to write zeros: have %1 need %2") 788 1130 .arg(space_on_soundcard).arg(fragment_size)); … … 818 1160 if (fragment_size > audiolen(true)) 819 1161 { 820 1162 if (audiolen(true) > 0) // only log if we're sending some audio 821 VERBOSE(VB_AUDIO , LOC +1163 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1164 QString("audio waiting for buffer to fill: " 823 1165 "have %1 want %2") 824 1166 .arg(audiolen(true)).arg(fragment_size)); 825 1167 826 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1168 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 827 1169 pthread_mutex_lock(&audio_buflock); 828 1170 pthread_cond_broadcast(&audio_bufsig); 829 1171 pthread_mutex_unlock(&audio_buflock); … … 837 1179 if (fragment_size > space_on_soundcard) 838 1180 { 839 1181 if (space_on_soundcard != last_space_on_soundcard) { 840 VERBOSE(VB_AUDIO , LOC +1182 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 841 1183 QString("audio waiting for space on soundcard: " 842 1184 "have %1 need %2") 843 1185 .arg(space_on_soundcard).arg(fragment_size)); … … 899 1241 900 1242 /* update raud */ 901 1243 raud = (raud + fragment_size) % AUDBUFSIZE; 902 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1244 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 903 1245 pthread_cond_broadcast(&audio_bufsig); 904 1246 905 1247 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); … … 3144 3161 new VerticalConfigurationGroup(false, false, true, true); 3145 3162 vgrp0->addChild(AC3PassThrough()); 3146 3163 vgrp0->addChild(DTSPassThrough()); 3164 addChild(MaxAudioChannels()); 3147 3165 3148 3166 VerticalConfigurationGroup *vgrp1 = 3149 3167 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;