Ticket #1104: mythtv_ac3.37.patch
File mythtv_ac3.37.patch, 117.6 KB (added by , 13 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 #ifdef ONEBLOCKATATIME 106 // append incoming data to the end of the input buffer 107 for (unsigned k=0;k<N/2;k++) { 108 inbuf[0][k+N/2] = input[0][k]; 109 inbuf[1][k+N/2] = input[1][k]; 110 } 111 // process first part 112 float *in_first[2] = {&inbuf[0][0],&inbuf[1][0]}; 113 add_output(in_first,output,center_width,dimension,adaption_rate,true); 114 // shift last half of input buffer to the beginning 115 for (unsigned k=0;k<N/2;k++) { 116 inbuf[0][k] = inbuf[0][k+N/2]; 117 inbuf[1][k] = inbuf[1][k+N/2]; 118 } 119 #else 120 // append incoming data to the end of the input buffer 121 for (unsigned k=0;k<N;k++) { 122 inbuf[0][k+N/2] = input[0][k]; 123 inbuf[1][k+N/2] = input[1][k]; 124 } 125 // process first part 126 float *in_first[2] = {&inbuf[0][0],&inbuf[1][0]}; 127 add_output(in_first,output,center_width,dimension,adaption_rate); 128 // process second part (overlapped) and return result 129 float *in_second[2] = {&inbuf[0][N/2],&inbuf[1][N/2]}; 130 add_output(in_second,output,center_width,dimension,adaption_rate,true); 131 // shift last third of input buffer to the beginning 132 for (unsigned k=0;k<N/2;k++) { 133 inbuf[0][k] = inbuf[0][k+N]; 134 inbuf[1][k] = inbuf[1][k+N]; 135 } 136 #endif 137 } 138 139 // flush the internal buffers 140 void flush() { 141 #ifdef ONEBLOCKATATIME 142 for (unsigned k=0;k<N;k++) { 143 for (unsigned c=0;c<6;c++) 144 outbuf[c][k] = 0; 145 inbuf[0][k] = 0; 146 inbuf[1][k] = 0; 147 } 148 #else 149 for (unsigned k=0;k<N+N/2;k++) { 150 for (unsigned c=0;c<6;c++) 151 outbuf[c][k] = 0; 152 inbuf[0][k] = 0; 153 inbuf[1][k] = 0; 154 } 155 #endif 156 } 157 158 // set the assumed surround mixing coefficients 159 void surround_coefficients(float a, float b) { 160 master_gain = 1.0; 161 // calc the simple coefficients 162 surround_high = a; 163 surround_low = b; 164 surround_balance = (a-b)/(a+b); 165 surround_level = 1/(a+b); 166 // calc the linear coefficients 167 cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0); 168 A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n; 169 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 170 } 171 172 // set the phase shifting mode 173 void phase_mode(unsigned mode) { 174 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; 175 phase_offsetL = modes[mode][0]; 176 phase_offsetR = modes[mode][1]; 177 } 178 179 // what steering mode should be chosen 180 void steering_mode(bool mode) { linear_steering = mode; } 181 182 // set front & rear separation controls 183 void separation(float front, float rear) { 184 front_separation = front; 185 rear_separation = rear; 186 } 187 188 private: 189 // polar <-> cartesian coodinates conversion 190 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); } 191 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); } 192 static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); } 193 static inline float sqr(float x) { return x*x; } 194 // the dreaded min/max 195 static inline float min(float a, float b) { return a<b?a:b; } 196 static inline float max(float a, float b) { return a>b?a:b; } 197 static inline float clamp(float x) { return max(-1,min(1,x)); } 198 199 // handle the output buffering for overlapped calls of block_decode 200 void add_output(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate, bool result=false) { 201 #ifdef ONEBLOCKATATIME 202 // add the windowed data to the last 1/2 of the output buffer 203 float *out[6] = {&outbuf[0][0],&outbuf[1][0],&outbuf[2][0],&outbuf[3][0],&outbuf[4][0],&outbuf[5][0]}; 204 block_decode(input,out,center_width,dimension,adaption_rate); 205 for (unsigned c=0;c<6;c++) { 206 // return the first 1/2 of the ouput buffer 207 for (unsigned k=0;k<N/2;k++) 208 output[c][k] = outbuf[c][k]; 209 // shift the last 1/2 to the first 1/2 of the output buffer 210 for (unsigned k=0;k<N/2;k++) 211 outbuf[c][k] = outbuf[c][k+N/2]; 212 // and clear the rest 213 for (unsigned k=N/2;k<N;k++) 214 outbuf[c][k] = 0; 215 } 216 #else 217 // add the windowed data to the last 2/3 of the output buffer 218 float *out[6] = {&outbuf[0][N/2],&outbuf[1][N/2],&outbuf[2][N/2],&outbuf[3][N/2],&outbuf[4][N/2],&outbuf[5][N/2]}; 219 block_decode(input,out,center_width,dimension,adaption_rate); 220 for (unsigned c=0;c<6;c++) { 221 if (result) 222 // return the first 2/3 of the ouput buffer 223 for (unsigned k=0;k<N;k++) 224 output[c][k] = outbuf[c][k]; 225 for (unsigned k=0;k<N;k++) 226 // shift the last 2/3 to the first 2/3 of the output buffer 227 outbuf[c][k] = outbuf[c][k+N/2]; 228 // and clear the rest 229 for (unsigned k=N;k<N+N/2;k++) 230 outbuf[c][k] = 0; 231 } 232 #endif 233 } 234 235 // CORE FUNCTION: decode a block of data 236 void block_decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 237 // 1. scale the input by the window function; this serves a dual purpose: 238 // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed 239 // - second it allows for smooth blending of varying filters between the blocks 240 for (unsigned k=0;k<N;k++) { 241 lt[k] = input[0][k] * wnd[k] * master_gain; 242 rt[k] = input[1][k] * wnd[k] * master_gain; 243 } 244 245 // ... and tranform it into the frequency domain 246 fftwf_execute(loadL); 247 fftwf_execute(loadR); 248 249 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 250 for (unsigned f=0;f<=N/2;f++) { 251 // get left/right amplitudes/phases 252 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 253 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); 254 // if (ampL+ampR < epsilon) 255 // continue; 256 257 // calculate the amplitude/phase difference 258 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 259 float phaseDiff = phaseL - phaseR; 260 if (phaseDiff < -PI) phaseDiff += 2*PI; 261 if (phaseDiff > PI) phaseDiff -= 2*PI; 262 phaseDiff = abs(phaseDiff); 263 264 if (linear_steering) { 265 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2); 266 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */ 267 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real(); 268 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G); 269 270 /* 271 Problem: 272 This assumes that the values are interpolated linearly between the cardinal points. 273 But this way we have no chance of knowing the average volume... 274 - Can we solve that computing everything under the assumption of normalized volume? 275 No. Seemingly not. 276 - Maybe we should add w explitcitly into the equation and see if we can solve it... 277 */ 278 279 280 //cfloat lt(0.5,0),rt(0.5,0); 281 //cfloat x(0,0), y(1,0); 282 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E); 283 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E); 284 cfloat s = sqrt(p*p/4.0f - q); 285 cfloat x = -p; 286 cfloat x1 = -p/2.0f + s; 287 cfloat x2 = -p/2.0f - s; 288 float x = 0; 289 if (x1.real() >= -1 && x1.real() <= 1) 290 x = x1.real(); 291 else if (x2.real() >= -1 && x2.real() <= 1) 292 x = x2.real();*/ 293 294 //cfloat yp = (rt - (x*E+H))/(F+x*G); 295 //cfloat xp = (lt - (y*B+D))/(A+y*C); 296 297 /*xfs[f] = x; 298 yfs[f] = y.real();*/ 299 300 // --- this is the fancy new linear mode --- 301 302 // get sound field x/y position 303 yfs[f] = get_yfs(ampDiff,phaseDiff); 304 xfs[f] = get_xfs(ampDiff,yfs[f]); 305 306 // add dimension control 307 yfs[f] = clamp(yfs[f] - dimension); 308 309 // add crossfeed control 310 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 311 312 // 3. generate frequency filters for each output channel 313 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 314 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 315 float volume[5] = { 316 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 317 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 318 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 319 back * surround_level * left, // left surround 320 back * surround_level * right // right surround 321 }; 322 323 // adapt the prior filter 324 for (unsigned c=0;c<5;c++) 325 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N; 326 327 } else { 328 // --- this is the old & simple steering mode --- 329 330 // calculate the amplitude/phase difference 331 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 332 float phaseDiff = phaseL - phaseR; 333 if (phaseDiff < -PI) phaseDiff += 2*PI; 334 if (phaseDiff > PI) phaseDiff -= 2*PI; 335 phaseDiff = abs(phaseDiff); 336 337 // determine sound field x-position 338 xfs[f] = ampDiff; 339 340 // determine preliminary sound field y-position from phase difference 341 yfs[f] = 1 - (phaseDiff/PI)*2; 342 343 if (abs(xfs[f]) > surround_balance) { 344 // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance 345 // this is necessary because the sound field is trapezoidal and will be stretched behind the listener 346 float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance); 347 yfs[f] = (1-frontness) * yfs[f] + frontness * 1; 348 } 349 350 // add dimension control 351 yfs[f] = clamp(yfs[f] - dimension); 352 353 // add crossfeed control 354 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 355 356 // 3. generate frequency filters for each output channel, according to the signal position 357 // the sum of all channel volumes must be 1.0 358 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 359 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 360 float volume[5] = { 361 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 362 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 363 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 364 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))), // left surround 365 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2))) // right surround 366 }; 367 368 // adapt the prior filter 369 for (unsigned c=0;c<5;c++) 370 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/N; 371 } 372 373 // ... and build the signal which we want to position 374 frontL[f] = polar(ampL+ampR,phaseL); 375 frontR[f] = polar(ampL+ampR,phaseR); 376 avg[f] = frontL[f] + frontR[f]; 377 surL[f] = polar(ampL+ampR,phaseL+phase_offsetL); 378 surR[f] = polar(ampL+ampR,phaseR+phase_offsetR); 379 #ifdef FILTERED_LFE 380 trueavg[f] = cfloat(dftL[f][0] + dftR[f][0], dftL[f][1] + dftR[f][1]); 381 #endif 382 } 383 384 // 4. distribute the unfiltered reference signals over the channels 385 apply_filter(&frontL[0],&filter[0][0],&output[0][0]); // front left 386 apply_filter(&avg[0], &filter[1][0],&output[1][0]); // front center 387 apply_filter(&frontR[0],&filter[2][0],&output[2][0]); // front right 388 apply_filter(&surL[0],&filter[3][0],&output[3][0]); // surround left 389 apply_filter(&surR[0],&filter[4][0],&output[4][0]); // surround right 390 #ifdef FILTERED_LFE 391 apply_filter(&trueavg[0],&filter[5][0],&output[5][0]); // lfe 392 #else 393 double g = master_gain; 394 // introduce a delay of N/2 too to match the other channels 395 for (unsigned k=0,k2=N/4;k<N/2;k++,k2++) { 396 output[5][k] = (input[0][k2] + input[1][k2]) * g; 397 } 398 #endif 399 } 400 401 #define FASTER_CALC 402 // map from amplitude difference and phase difference to yfs 403 inline double get_yfs(double ampDiff, double phaseDiff) { 404 double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2); 405 #ifdef FASTER_CALC 406 double tanX = tan(x); 407 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 408 + 0.09170680403453149*x*x*x + 0.2617754892323973*tanX - 0.04180413533856156*sqr(tanX); 409 #else 410 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 411 + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x)); 412 #endif 413 } 414 415 // map from amplitude difference and yfs to xfs 416 inline double get_xfs(double ampDiff, double yfs) { 417 double x=ampDiff,y=yfs; 418 #ifdef FASTER_CALC 419 double tanX = tan(x); 420 double tanY = tan(y); 421 double asinX = asin(x); 422 double sinX = sin(x); 423 double sinY = sin(y); 424 double x3 = x*x*x; 425 double y2 = y*y; 426 double y3 = y*y2; 427 return 2.464833559224702*x - 423.52131153259404*x*y + 428 67.8557858606918*x3*y + 788.2429425544392*x*y2 - 429 79.97650354902909*x3*y2 - 513.8966153850349*x*y3 + 430 35.68117670186306*x3*y3 + 13867.406173420834*y*asinX - 431 2075.8237075786396*y2*asinX - 908.2722068360281*y3*asinX - 432 12934.654772878019*asinX*sinY - 13216.736529661162*y*tanX + 433 1288.6463247741938*y2*tanX + 1384.372969378453*y3*tanX + 434 12699.231471126128*sinY*tanX + 95.37131275594336*sinX*tanY - 435 91.21223198407546*tanX*tanY; 436 #else 437 return 2.464833559224702*x - 423.52131153259404*x*y + 438 67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y - 439 79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y + 440 35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) - 441 2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) - 442 12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) + 443 1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) + 444 12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) - 445 91.21223198407546*tan(x)*tan(y); 446 #endif 447 } 448 449 // filter the complex source signal and add it to target 450 void apply_filter(cfloat *signal, float *flt, float *target) { 451 // filter the signal 452 for (unsigned f=0;f<=N/2;f++) { 453 src[f][0] = signal[f].real() * flt[f]; 454 src[f][1] = signal[f].imag() * flt[f]; 455 } 456 // transform into time domain 457 fftwf_execute(store); 458 // add the result to target, windowed 459 for (unsigned k=0;k<N;k++) 460 target[k] += wnd[k]*dst[k]; 461 } 462 463 unsigned N; // the block size 464 // FFTW data structures 465 float *lt,*rt,*dst; // left total, right total (source arrays), destination array 466 fftwf_complex *dftL,*dftR,*src; // intermediate arrays (FFTs of lt & rt, processing source) 467 fftwf_plan loadL,loadR,store; // plans for loading the data into the intermediate format and back 468 // buffers 469 std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain 470 #ifdef FILTERED_LFE 471 std::vector<cfloat> trueavg; // for lfe generation 472 #endif 473 std::vector<float> xfs,yfs; // the feature space positions for each frequency bin 474 std::vector<float> wnd; // the window function, precalculated 475 std::vector<float> filter[6]; // a frequency filter for each output channel 476 std::vector<float> inbuf[2]; // the sliding input buffers 477 std::vector<float> outbuf[6]; // the sliding output buffers 478 // coefficients 479 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 480 float surround_balance; // the xfs balance that follows from the coeffs 481 float surround_level; // gain for the surround channels (follows from the coeffs 482 float master_gain; // gain for all channels 483 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 484 float front_separation; // front stereo separation 485 float rear_separation; // rear stereo separation 486 bool linear_steering; // whether the steering should be linear or not 487 cfloat A,B,C,D,E,F,G,H; // coefficients for the linear steering 488 }; 489 490 491 // implementation of the shell class 492 493 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { } 494 495 fsurround_decoder::~fsurround_decoder() { delete impl; } 496 497 void fsurround_decoder::decode(float *input[2], float *output[6], float center_width, float dimension, float adaption_rate) { 498 impl->decode(input,output,center_width,dimension,adaption_rate); 499 } 500 501 void fsurround_decoder::flush() { impl->flush(); } 502 503 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 504 505 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 506 507 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); } 508 509 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 #define ONEBLOCKATATIME 23 24 // the Free Surround decoder 25 class fsurround_decoder { 26 public: 27 // create an instance of the decoder 28 // blocksize is fixed over the lifetime of this object for performance reasons 29 fsurround_decoder(unsigned blocksize=8192); 30 // destructor 31 ~fsurround_decoder(); 32 33 // decode a chunk of stereo sound, has to contain exactly blocksize samples 34 // center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution 35 // dimension [0..1] moves the soundfield backwards, 0=front, 1=side 36 // adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption 37 void decode(float *input[2], float *output[6], float center_width=1, float dimension=0, float adaption_rate=1); 38 39 // flush the internal buffers 40 void flush(); 41 42 // --- advanced configuration --- 43 44 // override the surround coefficients 45 // a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right. 46 void surround_coefficients(float a, float b); 47 48 // set the phase shifting mode for decoding 49 // 0 = (+0°,+0°) - music mode 50 // 1 = (+0°,+180°) - PowerDVD compatibility 51 // 2 = (+180°,+0°) - BeSweet compatibility 52 // 3 = (-90°,+90°) - This seems to work. I just don't know why. 53 void phase_mode(unsigned mode); 54 55 // override the steering mode 56 // false = simple non-linear steering (old) 57 // true = advanced linear steering (new) 58 void steering_mode(bool mode); 59 60 // set front/rear stereo separation 61 // 1.0 is default, 0.0 is mono 62 void separation(float front,float rear); 63 private: 64 class decoder_impl *impl; // private implementation (details hidden) 65 }; 66 67 68 #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 default_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 int block_size = default_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 lt(s),rt(s), 124 l(s),r(s),c(s),ls(s),rs(s),lfe(s) { } 125 void resize(unsigned int s) 126 { 127 lt.resize(s); rt.resize(s); 128 l.resize(s); r.resize(s); lfe.resize(s); 129 ls.resize(s); rs.resize(s); c.resize(s); 130 } 131 void clear() 132 { 133 lt.clear(); rt.clear(); l.clear(); r.clear(); 134 ls.clear(); rs.clear(); c.clear(); 135 } 136 std::vector<float> lt,rt; // for multiplexing 137 std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs; // for demultiplexing 138 }; 139 140 struct int16buffers 141 { 142 int16buffers(unsigned int s): 143 l(s),r(s),c(s),ls(s),rs(s),lfe(s) { } 144 void resize(unsigned int s) 145 { 146 l.resize(s); r.resize(s); lfe.resize(s); 147 ls.resize(s); rs.resize(s); c.resize(s); 148 } 149 void clear() 150 { 151 l.clear(); r.clear(); 152 ls.clear(); rs.clear(); c.clear(); 153 lfe.clear(); 154 } 155 std::vector<short> l,r,c,ls,rs,lfe; // for demultiplexing 156 }; 157 158 // construction methods 159 void *new_decoder() { return new fsurround_decoder(block_size); } 160 #ifdef ONEBLOCKATATIME 161 void *new_buffers() { return new buffers(block_size/2); } 162 void *new_int16buffers() { return new int16buffers(block_size/2); } 163 #else 164 void *new_buffers() { return new buffers(block_size); } 165 void *new_int16buffers() { return new int16buffers(block_size); } 166 #endif 167 168 object_pool dp(&new_decoder); 169 object_pool bp(&new_buffers); 170 object_pool bp16(&new_int16buffers); 171 172 //#define SPEAKERTEST 173 #ifdef SPEAKERTEST 174 int channel_select = -1; 175 #endif 176 177 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) : 178 srate(srate), 179 open_(false), 180 initialized_(false), 181 bufs(NULL), 182 int16bufs(NULL), 183 decoder(0), 184 in_count(0), 185 out_count(0), 186 processed(true), 187 surround_mode(smode) 188 { 189 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 190 if (moviemode) 191 { 192 params.phasemode = 1; 193 params.center_width = 0; 194 } 195 else 196 { 197 params.center_width = 50; 198 } 199 switch (surround_mode) 200 { 201 case SurroundModeActiveSimple: 202 params.steering = 0; 203 bufs = (buffers*)bp.acquire((void*)1); 204 break; 205 case SurroundModeActiveLinear: 206 params.steering = 1; 207 bufs = (buffers*)bp.acquire((void*)1); 208 break; 209 default: 210 int16bufs = (int16buffers*)bp16.acquire((void*)1); 211 break; 212 } 213 open(); 214 #ifdef SPEAKERTEST 215 channel_select++; 216 if (channel_select>=6) 217 channel_select = 0; 218 VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select)); 219 #endif 220 221 VERBOSE(QString("FreeSurround::FreeSurround done")); 222 } 223 224 FreeSurround::fsurround_params::fsurround_params( 225 int32_t center_width, 226 int32_t dimension 227 ) : 228 center_width(center_width), 229 dimension(dimension), 230 coeff_a(0.8165),coeff_b(0.5774), 231 phasemode(0), 232 steering(1), 233 front_sep(100), 234 rear_sep(100) 235 { 236 } 237 238 FreeSurround::~FreeSurround() 239 { 240 VERBOSE(QString("FreeSurround::~FreeSurround")); 241 close(); 242 if (bufs) 243 { 244 bp.release((void*)1); 245 bufs = NULL; 246 } 247 if (int16bufs) 248 { 249 bp16.release((void*)1); 250 int16bufs = NULL; 251 } 252 VERBOSE(QString("FreeSurround::~FreeSurround done")); 253 } 254 255 uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step) 256 { 257 int i; 258 int ic = in_count; 259 #ifdef ONEBLOCKATATIME 260 int bs = block_size/2; 261 #else 262 int bs = block_size; 263 #endif 264 bool process = true; 265 // demultiplex 266 switch (surround_mode) 267 { 268 case SurroundModePassive: 269 switch (numChannels) 270 { 271 case 1: 272 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 273 { 274 int16bufs->l[ic] = 275 int16bufs->c[ic] = 276 int16bufs->r[ic] = 277 samples[i] * master_gain; 278 } 279 break; 280 case 2: 281 if (step>0) 282 { 283 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 284 { 285 short lt = samples[i]; 286 short rt = samples[i+step]; 287 int16bufs->l[ic] = lt; 288 int16bufs->lfe[ic] = 289 int16bufs->c[ic] = (lt+rt)>>1; 290 int16bufs->r[ic] = rt; 291 int16bufs->ls[ic] = 292 int16bufs->rs[ic] = (lt-rt)>>1; 293 } 294 } 295 else 296 { 297 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 298 { 299 short lt = samples[i*2]; 300 short rt = samples[i*2+1]; 301 int16bufs->l[ic] = lt; 302 int16bufs->lfe[ic] = 303 int16bufs->c[ic] = (lt+rt)>>1; 304 int16bufs->r[ic] = rt; 305 int16bufs->ls[ic] = 306 int16bufs->rs[ic] = (lt-rt)>>1; 307 } 308 } 309 break; 310 case 6: 311 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 312 { 313 int16bufs->l[ic] = *samples++; 314 int16bufs->c[ic] = *samples++; 315 int16bufs->r[ic] = *samples++; 316 int16bufs->ls[ic] = *samples++; 317 int16bufs->rs[ic] = *samples++; 318 int16bufs->lfe[ic] = *samples++; 319 } 320 break; 321 } 322 in_count = 0; 323 out_count = ic; 324 processed_size = ic; 325 break; 326 327 default: 328 switch (numChannels) 329 { 330 case 1: 331 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 332 { 333 bufs->lt[ic] = 334 bufs->rt[ic] = 335 samples[i] * master_gain; 336 } 337 break; 338 case 2: 339 if (step>0) 340 { 341 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 342 { 343 bufs->lt[ic] = samples[i] * master_gain; 344 bufs->rt[ic] = samples[i+step] * master_gain; 345 } 346 } 347 else 348 { 349 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 350 { 351 bufs->lt[ic] = samples[i*2] * master_gain; 352 bufs->rt[ic] = samples[i*2+1] * master_gain; 353 } 354 } 355 break; 356 case 6: 357 process = false; 358 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 359 { 360 bufs->l[ic] = *samples++ * master_gain; 361 bufs->c[ic] = *samples++ * master_gain; 362 bufs->r[ic] = *samples++ * master_gain; 363 bufs->ls[ic] = *samples++ * master_gain; 364 bufs->rs[ic] = *samples++ * master_gain; 365 bufs->lfe[ic] = *samples++ * master_gain; 366 } 367 break; 368 } 369 in_count = ic; 370 processed = process; 371 if (ic == bs) 372 { 373 in_count = 0; 374 if (process) 375 process_block(); 376 out_count = bs; 377 processed_size = bs; 378 } 379 break; 380 } 381 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 382 .arg(numSamples) 383 .arg(numChannels) 384 .arg(step) 385 .arg(i) 386 .arg(out_count) 387 ); 388 return i; 389 } 390 391 uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step) 392 { 393 int i; 394 int ic = in_count; 395 #ifdef ONEBLOCKATATIME 396 int bs = block_size/2; 397 #else 398 int bs = block_size; 399 #endif 400 bool process = true; 401 // demultiplex 402 switch (surround_mode) 403 { 404 case SurroundModePassive: 405 switch (numChannels) 406 { 407 case 1: 408 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 409 { 410 int16bufs->l[ic] = 411 int16bufs->c[ic] = 412 int16bufs->r[ic] = 413 samples[i] * master_gain; 414 } 415 break; 416 case 2: 417 if (step>0) 418 { 419 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 420 { 421 short lt = samples[i]; 422 short rt = samples[i+step]; 423 int16bufs->l[ic] = lt; 424 int16bufs->lfe[ic] = 425 int16bufs->c[ic] = (lt+rt)>>1; 426 int16bufs->r[ic] = rt; 427 int16bufs->ls[ic] = 428 int16bufs->rs[ic] = (lt-rt)>>1; 429 } 430 } 431 else 432 { 433 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 434 { 435 short lt = samples[i*2]; 436 short rt = samples[i*2+1]; 437 int16bufs->l[ic] = lt; 438 int16bufs->lfe[ic] = 439 int16bufs->c[ic] = (lt+rt)>>1; 440 int16bufs->r[ic] = rt; 441 int16bufs->ls[ic] = 442 int16bufs->rs[ic] = (lt-rt)>>1; 443 } 444 } 445 break; 446 case 6: 447 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 448 { 449 int16bufs->l[ic] = *samples++; 450 int16bufs->c[ic] = *samples++; 451 int16bufs->r[ic] = *samples++; 452 int16bufs->ls[ic] = *samples++; 453 int16bufs->rs[ic] = *samples++; 454 int16bufs->lfe[ic] = *samples++; 455 } 456 break; 457 } 458 in_count = 0; 459 out_count = ic; 460 processed_size = ic; 461 break; 462 463 default: 464 switch (numChannels) 465 { 466 case 1: 467 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 468 { 469 bufs->lt[ic] = 470 bufs->rt[ic] = 471 samples[i] * master_gain; 472 } 473 break; 474 case 2: 475 if (step>0) 476 { 477 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 478 { 479 bufs->lt[ic] = samples[i] * master_gain; 480 bufs->rt[ic] = samples[i+step] * master_gain; 481 } 482 } 483 else 484 { 485 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 486 { 487 bufs->lt[ic] = samples[i*2] * master_gain; 488 bufs->rt[ic] = samples[i*2+1] * master_gain; 489 } 490 } 491 break; 492 case 6: 493 process = false; 494 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 495 { 496 bufs->l[ic] = *samples++ * master_gain; 497 bufs->c[ic] = *samples++ * master_gain; 498 bufs->r[ic] = *samples++ * master_gain; 499 bufs->ls[ic] = *samples++ * master_gain; 500 bufs->rs[ic] = *samples++ * master_gain; 501 bufs->lfe[ic] = *samples++ * master_gain; 502 } 503 break; 504 } 505 in_count = ic; 506 processed = process; 507 if (ic == bs) 508 { 509 in_count = 0; 510 if (process) 511 process_block(); 512 out_count = bs; 513 processed_size = bs; 514 } 515 break; 516 } 517 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 518 .arg(numSamples) 519 .arg(numChannels) 520 .arg(step) 521 .arg(i) 522 .arg(out_count) 523 ); 524 return i; 525 } 526 527 uint FreeSurround::receiveSamples( 528 short *output, 529 uint maxSamples 530 ) 531 { 532 uint i; 533 uint oc = out_count; 534 if (maxSamples>oc) maxSamples = oc; 535 uint outindex = processed_size - oc; 536 switch (surround_mode) 537 { 538 case SurroundModePassive: 539 for (unsigned int i=0;i<maxSamples;i++) 540 { 541 *output++ = int16bufs->l[outindex]; 542 *output++ = int16bufs->r[outindex]; 543 *output++ = int16bufs->ls[outindex]; 544 *output++ = int16bufs->rs[outindex]; 545 *output++ = int16bufs->c[outindex]; 546 *output++ = int16bufs->lfe[outindex]; 547 oc--; 548 outindex++; 549 } 550 break; 551 552 default: 553 for (unsigned int i=0;i<maxSamples;i++) 554 { 555 *output++ = lrintf(bufs->l[outindex] * inv_master_gain); 556 *output++ = lrintf(bufs->r[outindex] * inv_master_gain); 557 *output++ = lrintf(bufs->ls[outindex] * inv_master_gain); 558 *output++ = lrintf(bufs->rs[outindex] * inv_master_gain); 559 *output++ = lrintf(bufs->c[outindex] * inv_master_gain); 560 *output++ = lrintf(bufs->lfe[outindex] * inv_master_gain); 561 oc--; 562 outindex++; 563 } 564 break; 565 } 566 out_count = oc; 567 VERBOSE1(QString("FreeSurround::receiveSamples %1") 568 .arg(maxSamples) 569 ); 570 return maxSamples; 571 } 572 573 void FreeSurround::process_block() 574 { 575 // process the data 576 try 577 { 578 float *input[2] = {&bufs->lt[0], &bufs->rt[0]}; 579 float *output[8] = {&bufs->l[0], &bufs->c[0], &bufs->r[0], &bufs->ls[0], &bufs->rs[0], &bufs->lfe[0], &bufs->lcs[0], &bufs->rcs[0]}; 580 if (decoder) 581 { 582 // actually these params need only be set when they change... but it doesn't hurt 583 decoder->steering_mode(params.steering); 584 decoder->phase_mode(params.phasemode); 585 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 586 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 587 // decode the bufs->block 588 decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0); 589 } 590 } 591 catch(...) 592 { 593 //throw(std::runtime_error(std::string("error during processing (unsupported input format?)"))); 594 } 595 } 596 597 long long FreeSurround::getLatency() 598 { 599 // returns in usec 600 if (surround_mode == SurroundModePassive) 601 return 0; 602 #ifdef ONEBLOCKATATIME 603 return decoder ? ((block_size/2 + in_count)*1000000)/(2*srate) : 0; 604 #else 605 return decoder ? ((block_size + in_count)*1000000)/(2*srate) : 0; 606 #endif 607 } 608 609 void FreeSurround::flush() 610 { 611 if (decoder) 612 decoder->flush(); 613 bufs->clear(); 614 } 615 616 // load the lib and initialize the interface 617 void FreeSurround::open() 618 { 619 if (!decoder) 620 { 621 decoder = (fsurround_decoder*)dp.acquire((void*)1); 622 decoder->flush(); 623 if (bufs) 624 bufs->clear(); 625 if (int16bufs) 626 int16bufs->clear(); 627 } 628 } 629 630 void FreeSurround::close() 631 { 632 if (decoder) 633 { 634 dp.release(this); 635 decoder = 0; 636 } 637 } 638 639 uint FreeSurround::numUnprocessedSamples() 640 { 641 return in_count; 642 } 643 644 uint FreeSurround::numSamples() 645 { 646 return out_count; 647 } 648 649 uint FreeSurround::sampleLatency() 650 { 651 if (processed && (surround_mode != SurroundModePassive)) 652 return in_count + out_count + (block_size/2); 653 else 654 return in_count + out_count; 655 } 656 657 uint FreeSurround::samplesPerBlock() 658 { 659 #ifdef ONEBLOCKATATIME 660 return block_size/2; 661 #else 662 return block_size; 663 #endif 664 } 665 -
libs/libmythfreesurround/freesurround.h
1 /* 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 typedef enum 26 { 27 SurroundModePassive, 28 SurroundModeActiveSimple, 29 SurroundModeActiveLinear 30 } SurroundMode; 31 public: 32 FreeSurround(uint srate, bool moviemode, SurroundMode mode); 33 ~FreeSurround(); 34 35 // put samples in buffer, returns number of samples used 36 uint putSamples(short* samples, uint numSamples, uint numChannels, int step); 37 uint putSamples(char* samples, uint numSamples, uint numChannels, int step); 38 // get a number of samples 39 uint receiveSamples(short *output, 40 uint maxSamples 41 ); 42 // flush unprocessed samples 43 void flush(); 44 //void setSampleRate(uint srate); 45 uint numUnprocessedSamples(); 46 uint numSamples(); 47 48 long long getLatency(); 49 uint sampleLatency(); 50 51 uint samplesPerBlock(); 52 53 protected: 54 void process_block(); 55 void open(); 56 void close(); 57 58 private: 59 60 // the changeable parameters 61 struct fsurround_params { 62 int32_t center_width; // presence of the center channel 63 int32_t dimension; // dimension 64 float coeff_a,coeff_b; // surround mixing coefficients 65 int32_t phasemode; // phase shifting mode 66 int32_t steering; // steering mode (0=simple, 1=linear) 67 int32_t front_sep, rear_sep;// front/rear stereo separation 68 69 // (default) constructor 70 fsurround_params(int32_t center_width=100, int32_t dimension=0); 71 } params; 72 73 // additional settings 74 uint srate; 75 76 // info about the current setup 77 bool open_; // whether a stream is currently open 78 bool initialized_; // whether the thing is intialized 79 struct buffers *bufs; // our buffers 80 struct int16buffers *int16bufs; // our buffers 81 class fsurround_decoder *decoder; // the surround decoder 82 int in_count; // amount in lt,rt 83 int out_count; // amount in output bufs 84 bool processed; // whether processing is enabled or not for latency calc 85 int processed_size; // amount processed 86 SurroundMode surround_mode; // 1 of 3 surround modes supported 87 88 }; 89 90 #endif 91 -
libs/libmythfreesurround/libmythfreesurround.pro
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 int surround_mode; 174 148 175 bool blocking; // do AddSamples calls block? 149 176 150 177 int lastaudiolen; … … 162 189 163 190 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 164 191 'audiotime' and 'audiotime_updated' */ 165 intaudiotime; // timecode of audio leaving the soundcard (same units as192 long long audiotime; // timecode of audio leaving the soundcard (same units as 166 193 // timecodes) ... 167 194 struct timeval audiotime_updated; // ... which was last updated at this time 168 195 169 196 /* Audio circular buffer */ 170 197 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 171 198 int raud, waud; /* read and write positions */ 172 intaudbuf_timecode; /* timecode of audio most recently placed into199 long long audbuf_timecode; /* timecode of audio most recently placed into 173 200 buffer */ 174 201 175 202 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), 62 surround_mode(FreeSurround::SurroundModePassive), 51 63 64 blocking(false), 65 52 66 lastaudiolen(0), samples_buffered(0), 53 67 54 68 audio_thread_exists(false), … … 71 85 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 86 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 87 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 88 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 89 75 90 // You need to call Reconfigure from your concrete class. 76 91 // Reconfigure(laudio_bits, laudio_channels, … … 111 126 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 127 .arg(audio_stretchfactor)); 113 128 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 129 if (audio_codec) 130 { 131 if (!encoder) 132 { 133 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 134 encoder = new AudioOutputDigitalEncoder(); 135 if (!encoder->Init(audio_codec->codec_id, 136 audio_codec->bit_rate, 137 audio_codec->sample_rate, 138 audio_codec->channels 139 )) 140 { 141 // eeks 142 delete encoder; 143 encoder = NULL; 144 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 145 } 146 } 147 } 148 if (encoder) 149 { 150 pSoundStretch->setSampleRate(audio_codec->sample_rate); 151 pSoundStretch->setChannels(audio_codec->channels); 152 } 153 else 154 { 155 pSoundStretch->setSampleRate(audio_samplerate); 156 pSoundStretch->setChannels(audio_channels); 157 } 116 158 117 159 pSoundStretch->setTempo(audio_stretchfactor); 118 160 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 135 177 } 136 178 137 179 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 180 int laudio_samplerate, bool laudio_passthru, 181 void* laudio_codec) 139 182 { 183 int codec_id = CODEC_ID_NONE; 184 int lcodec_id = CODEC_ID_NONE; 185 int lcchannels = 0; 186 int cchannels = 0; 187 int lsource_audio_channels = laudio_channels; 188 bool lneeds_upmix = false; 189 190 if (laudio_codec) 191 { 192 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 193 laudio_bits = 16; 194 laudio_channels = 2; 195 lsource_audio_channels = laudio_channels; 196 laudio_samplerate = 48000; 197 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 198 } 199 if (audio_codec) 200 { 201 codec_id = audio_codec->codec_id; 202 cchannels = ((AVCodecContext*)audio_codec)->channels; 203 } 204 if ((configured_audio_channels == 6) && 205 !(laudio_codec || audio_codec)) 206 { 207 #if !UPMIXINLOOP 208 laudio_channels = configured_audio_channels; 209 #endif 210 lneeds_upmix = true; 211 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 212 } 213 ClearError(); 140 214 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 215 laudio_samplerate == audio_samplerate && !need_resampler && 216 laudio_passthru == audio_passthru && 217 lneeds_upmix == needs_upmix && 218 lcodec_id == codec_id && lcchannels == cchannels) 219 { 220 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 221 return; 144 222 } 145 223 KillAudio(); 146 224 147 225 pthread_mutex_lock(&audio_buflock); … … 151 229 waud = raud = 0; 152 230 audio_actually_paused = false; 153 231 232 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 233 audio_channels = laudio_channels; 234 #if !UPMIXINLOOP 235 source_audio_channels = lsource_audio_channels; 236 #endif 155 237 audio_bits = laudio_bits; 156 238 audio_samplerate = laudio_samplerate; 239 audio_codec = (AVCodecContext*)laudio_codec; 157 240 audio_passthru = laudio_passthru; 241 needs_upmix = lneeds_upmix; 158 242 if (audio_bits != 8 && audio_bits != 16) 159 243 { 160 244 pthread_mutex_unlock(&avsync_lock); … … 163 247 return; 164 248 } 165 249 audio_bytes_per_sample = audio_channels * audio_bits / 8; 250 #if !UPMIXINLOOP 251 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 252 #endif 166 253 167 254 need_resampler = false; 168 255 killaudio = false; … … 172 259 173 260 numlowbuffer = 0; 174 261 262 #if UPMIXINLOOP 263 int fake_channels = audio_channels; 264 audio_channels = configured_audio_channels; 265 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 266 .arg(audio_main_device).arg(configured_audio_channels) 267 .arg(audio_channels).arg(audio_samplerate)); 268 175 269 // Actually do the device specific open call 270 bool openresult = OpenDevice(); 271 audio_channels = fake_channels; 272 if (!openresult) 273 #else 274 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 275 .arg(audio_main_device).arg(audio_channels) 276 .arg(source_audio_channels).arg(audio_samplerate)); 277 278 // Actually do the device specific open call 176 279 if (!OpenDevice()) 280 #endif 177 281 { 178 282 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 283 pthread_mutex_unlock(&avsync_lock); 180 284 pthread_mutex_unlock(&audio_buflock); 285 if (GetError().isEmpty()) 286 Error("Aborting reconfigure"); 287 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 288 return; 182 289 } 183 290 … … 200 307 current_seconds = -1; 201 308 source_bitrate = -1; 202 309 310 // NOTE: this wont do anything as above samplerate vars are set equal 203 311 // Check if we need the resampler 204 312 if (audio_samplerate != laudio_samplerate) 205 313 { … … 222 330 need_resampler = true; 223 331 } 224 332 333 if (needs_upmix) 334 { 335 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 336 if (configured_audio_channels == 6) 337 { 338 surround_mode = gContext->GetNumSetting("AudioUpmixType", 2); 339 } 340 upmixer = new FreeSurround(audio_samplerate, 341 source == AUDIOOUTPUT_VIDEO, 342 (FreeSurround::SurroundMode)surround_mode); 343 VERBOSE(VB_AUDIO, LOC + QString("create upmixer done with surround mode %1").arg(surround_mode)); 344 } 345 225 346 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 347 .arg(audio_stretchfactor)); 348 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 349 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 227 350 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 351 if (redo_stretch) 230 352 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 353 float laudio_stretchfactor = audio_stretchfactor; 354 delete pSoundStretch; 355 pSoundStretch = NULL; 356 audio_stretchfactor = 0.0; 357 SetStretchFactorLocked(laudio_stretchfactor); 233 358 } 359 else 360 { 361 SetStretchFactorLocked(audio_stretchfactor); 362 if (pSoundStretch) 363 { 364 // if its passthru then we need to reencode 365 if (audio_codec) 366 { 367 if (!encoder) 368 { 369 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 370 encoder = new AudioOutputDigitalEncoder(); 371 if (!encoder->Init(audio_codec->codec_id, 372 audio_codec->bit_rate, 373 audio_codec->sample_rate, 374 audio_codec->channels 375 )) 376 { 377 // eeks 378 delete encoder; 379 encoder = NULL; 380 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 381 } 382 } 383 } 384 if (encoder) 385 { 386 pSoundStretch->setSampleRate(audio_codec->sample_rate); 387 pSoundStretch->setChannels(audio_codec->channels); 388 } 389 else 390 { 391 pSoundStretch->setSampleRate(audio_samplerate); 392 pSoundStretch->setChannels(audio_channels); 393 } 394 } 395 } 234 396 235 397 // Setup visualisations, zero the visualisations buffers 236 398 prepareVisuals(); … … 290 452 pSoundStretch = NULL; 291 453 } 292 454 455 if (encoder) 456 { 457 delete encoder; 458 encoder = NULL; 459 } 460 461 if (upmixer) 462 { 463 delete upmixer; 464 upmixer = NULL; 465 } 466 needs_upmix = false; 467 293 468 CloseDevice(); 294 469 295 470 killAudioLock.unlock(); … … 303 478 304 479 void AudioOutputBase::Pause(bool paused) 305 480 { 481 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 306 482 pauseaudio = paused; 307 483 audio_actually_paused = false; 308 484 } … … 385 561 The reason is that computing 'audiotime' requires acquiring the audio 386 562 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 563 from the audio thread, and then call this from the video thread. */ 388 intret;564 long long ret; 389 565 struct timeval now; 390 566 391 567 if (audiotime == 0) … … 397 573 398 574 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 575 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);576 ret = (long long)(ret * audio_stretchfactor); 401 577 578 #if 1 579 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 580 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 581 .arg(now.tv_sec).arg(now.tv_usec) 582 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 583 .arg(ret) 584 .arg(audiotime) 585 .arg(audio_stretchfactor) 586 ); 587 #endif 588 402 589 ret += audiotime; 403 590 404 591 pthread_mutex_unlock(&avsync_lock); 405 return ret;592 return (int)ret; 406 593 } 407 594 408 595 void AudioOutputBase::SetAudiotime(void) … … 439 626 // include algorithmic latencies 440 627 if (pSoundStretch) 441 628 { 629 // add the effect of any unused but processed samples, AC3 reencode does this 630 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 442 631 // add the effect of unprocessed samples in time stretch algo 443 632 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 633 audio_bytes_per_sample) / audio_stretchfactor); 445 634 } 446 635 636 #if !UPMIXINLOOP 637 if (upmixer && needs_upmix) 638 { 639 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 640 } 641 #endif 642 447 643 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 644 (audio_bytes_per_sample * effdspstretched)); 449 645 450 646 gettimeofday(&audiotime_updated, NULL); 647 #if 1 648 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 649 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 650 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 651 .arg(audiotime) 652 .arg(audbuf_timecode) 653 .arg(totalbuffer) 654 .arg(soundcard_buffer) 655 .arg(effdspstretched) 656 .arg(audio_bytes_per_sample) 657 .arg(audio_stretchfactor) 658 ); 659 #endif 451 660 452 661 pthread_mutex_unlock(&avsync_lock); 453 662 pthread_mutex_unlock(&audio_buflock); … … 464 673 if (need_resampler && src_ctx) 465 674 len = (int)ceilf(float(len) * src_data.src_ratio); 466 675 676 #if !UPMIXINLOOP 677 // include samples in upmix buffer that may be flushed 678 if (needs_upmix && upmixer) 679 len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample; 680 #endif 681 467 682 if ((len > afree) && !blocking) 468 683 { 469 684 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( … … 515 730 // NOTE: This function is not threadsafe 516 731 517 732 int afree = audiofree(true); 518 int len = samples * audio_bytes_per_sample;733 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 519 734 520 735 // Check we have enough space to write the data 521 736 if (need_resampler && src_ctx) 522 737 len = (int)ceilf(float(len) * src_data.src_ratio); 523 738 739 #if !UPMIXINLOOP 740 // include samples in upmix buffer that may be flushed 741 if (needs_upmix && upmixer) 742 len += upmixer->numUnprocessedSamples()*audio_bytes_per_sample; 743 #endif 744 524 745 if ((len > afree) && !blocking) 525 746 { 526 747 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString( 527 748 "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 528 749 .arg(len).arg(AUDBUFSIZE-afree).arg(afree) 529 750 .arg(timecode)); 530 531 751 return false; // would overflow 532 752 } 533 753 … … 562 782 return true; 563 783 } 564 784 565 int AudioOutputBase::WaitForFreeSpace(int samples )785 int AudioOutputBase::WaitForFreeSpace(int samples, bool wait_min) 566 786 { 567 int len = samples * audio_bytes_per_sample; 787 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 788 int len = samples * abps; 568 789 int afree = audiofree(false); 569 790 570 791 while (len > afree) 571 792 { 572 793 if (blocking) 573 794 { 574 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +795 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 575 796 QString("(need %1, available %2)").arg(len).arg(afree)); 576 797 577 798 // wait for more space … … 580 801 } 581 802 else 582 803 { 583 VERBOSE(VB_IMPORTANT, LOC_ERR + 584 "Audio buffer overflow, audio data lost!"); 585 samples = afree / audio_bytes_per_sample; 586 len = samples * audio_bytes_per_sample; 804 if (wait_min) 805 { 806 int time_to_wait = ((len-afree)*1000000)/(audio_samplerate*abps); 807 pthread_mutex_unlock(&audio_buflock); 808 usleep(time_to_wait + 5000); // 5ms extra to allow for output loop 809 pthread_mutex_lock(&audio_buflock); 810 afree = audiofree(false); 811 wait_min = false; // do it once only 812 continue; 813 } 814 VERBOSE(VB_IMPORTANT, LOC_ERR + 815 QString("Audio buffer overflow, %1 audio samples lost!") 816 .arg(samples-afree / abps)); 817 samples = afree / abps; 818 len = samples * abps; 587 819 if (src_ctx) 588 820 { 589 821 int error = src_reset(src_ctx); … … 608 840 609 841 int afree = audiofree(false); 610 842 611 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 612 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 613 .arg(samples * audio_bytes_per_sample) 614 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 843 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 844 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 845 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6 upmixer %7") 846 .arg(samples) 847 .arg(samples * abps) 848 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 849 .arg(needs_upmix).arg((uint)(void*)upmixer) 850 ); 615 851 616 len = WaitForFreeSpace(samples); 617 618 if (interleaved) 852 #if !UPMIXINLOOP 853 if (upmixer && needs_upmix) 619 854 { 620 char *mybuf = (char*)buffer; 621 int bdiff = AUDBUFSIZE - org_waud; 622 if (bdiff < len) 855 int out_samples = 0; 856 int step = (interleaved)?source_audio_channels:1; 857 len = WaitForFreeSpace(samples, true); // test 858 for(int itemp=0; itemp<samples; ) 623 859 { 624 memcpy(audiobuffer + org_waud, mybuf, bdiff); 625 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 860 // just in case it does a processing cycle, release the lock 861 // to allow the output loop to do output 862 pthread_mutex_unlock(&audio_buflock); 863 if (audio_bytes == 2) 864 itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 865 else 866 itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 867 pthread_mutex_lock(&audio_buflock); 868 869 int copy_samples = upmixer->numSamples(); 870 if (copy_samples) 871 { 872 int copy_len = copy_samples * abps; 873 out_samples += copy_samples; 874 if (out_samples > samples) 875 len = WaitForFreeSpace(out_samples, true); 876 int bdiff = AUDBUFSIZE - org_waud; 877 if (bdiff < copy_len) 878 { 879 int bdiff_samples = bdiff/abps; 880 upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples); 881 upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples)); 882 } 883 else 884 { 885 upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples); 886 } 887 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 888 } 626 889 } 627 else 628 memcpy(audiobuffer + org_waud, mybuf, len); 629 630 org_waud = (org_waud + len) % AUDBUFSIZE; 631 } 632 else 890 if (samples > 0) 891 { 892 len = WaitForFreeSpace(out_samples, true); 893 } 894 samples = out_samples; 895 } 896 else 897 #endif 633 898 { 634 char **mybuf = (char**)buffer; 635 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 899 len = WaitForFreeSpace(samples, true); 900 901 if (interleaved) 636 902 { 637 for (int chan = 0; chan < audio_channels; chan++) 903 char *mybuf = (char*)buffer; 904 int bdiff = AUDBUFSIZE - org_waud; 905 if (bdiff < len) 638 906 { 639 audiobuffer[org_waud++] = mybuf[chan][itemp]; 640 if (audio_bits == 16) 641 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 907 memcpy(audiobuffer + org_waud, mybuf, bdiff); 908 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 909 } 910 else 911 memcpy(audiobuffer + org_waud, mybuf, len); 912 913 org_waud = (org_waud + len) % AUDBUFSIZE; 914 } 915 else 916 { 917 char **mybuf = (char**)buffer; 918 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 919 { 920 for (int chan = 0; chan < audio_channels; chan++) 921 { 922 audiobuffer[org_waud++] = mybuf[chan][itemp]; 923 if (audio_bits == 16) 924 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 642 925 643 if (org_waud >= AUDBUFSIZE) 644 org_waud -= AUDBUFSIZE; 926 if (org_waud >= AUDBUFSIZE) 927 org_waud -= AUDBUFSIZE; 928 } 645 929 } 646 930 } 647 931 } 648 932 649 if (pSoundStretch) 933 #if !UPMIXINLOOP 934 if (samples > 0) 935 #endif 650 936 { 651 // does not change the timecode, only the number of samples 652 // back to orig pos 653 org_waud = waud; 654 int bdiff = AUDBUFSIZE - org_waud; 655 int nSamplesToEnd = bdiff/audio_bytes_per_sample; 656 if (bdiff < len) 937 if (pSoundStretch) 657 938 { 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 939 669 int newLen = 0; 670 int nSamples; 671 len = WaitForFreeSpace(pSoundStretch->numSamples() * 672 audio_bytes_per_sample); 673 do 674 { 675 int samplesToGet = len/audio_bytes_per_sample; 676 if (samplesToGet > nSamplesToEnd) 940 // does not change the timecode, only the number of samples 941 // back to orig pos 942 org_waud = waud; 943 int bdiff = AUDBUFSIZE - org_waud; 944 int nSamplesToEnd = bdiff/abps; 945 if (bdiff < len) 677 946 { 678 samplesToGet = nSamplesToEnd; 947 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 948 org_waud), nSamplesToEnd); 949 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 950 (len - bdiff) / abps); 679 951 } 952 else 953 { 954 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 955 org_waud), len / abps); 956 } 680 957 681 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 682 (audiobuffer + org_waud), samplesToGet); 683 if (nSamples == nSamplesToEnd) 958 if (encoder) 684 959 { 685 org_waud = 0; 686 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 960 // pull out a packet's worth and reencode it until we dont have enough 961 // for any more packets 962 soundtouch::SAMPLETYPE* temp_buff = 963 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 964 size_t frameSize = encoder->FrameSize()/abps; 965 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 966 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 967 .arg(frameSize) 968 .arg(encoder->FrameSize()) 969 .arg(pSoundStretch->numSamples()) 970 ); 971 // process the same number of samples as it creates a full encoded buffer 972 // just like before 973 while (pSoundStretch->numSamples() >= frameSize) 974 { 975 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 976 int amount = encoder->Encode(temp_buff); 977 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 978 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 979 .arg(amount) 980 .arg(got) 981 .arg(pSoundStretch->numSamples()) 982 ); 983 if (amount == 0) 984 continue; 985 //len = WaitForFreeSpace(amount); 986 char * ob = encoder->GetOutBuff(); 987 if (amount >= bdiff) 988 { 989 memcpy(audiobuffer + org_waud, ob, bdiff); 990 ob += bdiff; 991 amount -= bdiff; 992 org_waud = 0; 993 } 994 if (amount > 0) 995 memcpy(audiobuffer + org_waud, ob, amount); 996 bdiff = AUDBUFSIZE - amount; 997 org_waud += amount; 998 } 687 999 } 688 1000 else 689 1001 { 690 org_waud += nSamples * audio_bytes_per_sample; 691 nSamplesToEnd -= nSamples; 1002 int newLen = 0; 1003 int nSamples; 1004 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1005 audio_bytes_per_sample, true); 1006 do 1007 { 1008 int samplesToGet = len/audio_bytes_per_sample; 1009 if (samplesToGet > nSamplesToEnd) 1010 { 1011 samplesToGet = nSamplesToEnd; 1012 } 1013 1014 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1015 (audiobuffer + org_waud), samplesToGet); 1016 if (nSamples == nSamplesToEnd) 1017 { 1018 org_waud = 0; 1019 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1020 } 1021 else 1022 { 1023 org_waud += nSamples * audio_bytes_per_sample; 1024 nSamplesToEnd -= nSamples; 1025 } 1026 1027 newLen += nSamples * audio_bytes_per_sample; 1028 len -= nSamples * audio_bytes_per_sample; 1029 } while (nSamples > 0); 692 1030 } 1031 } 693 1032 694 newLen += nSamples * audio_bytes_per_sample; 695 len -= nSamples * audio_bytes_per_sample; 696 } while (nSamples > 0); 697 } 1033 waud = org_waud; 1034 lastaudiolen = audiolen(false); 698 1035 699 waud = org_waud; 700 lastaudiolen = audiolen(false); 1036 if (timecode < 0) 1037 { 1038 // mythmusic doesn't give timestamps.. 1039 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1040 } 1041 1042 samples_buffered += samples; 1043 1044 /* we want the time at the end -- but the file format stores 1045 time at the start of the chunk. */ 1046 // even with timestretch, timecode is still calculated from original 1047 // sample count 1048 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 701 1049 702 samples_buffered += samples;703 704 if (timecode < 0)705 { 706 // mythmusic doesn't give timestamps..707 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1050 if (interleaved) 1051 #if UPMIXINLOOP 1052 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits); 1053 #else 1054 dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits); 1055 #endif 708 1056 } 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 1057 716 if (interleaved)717 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);718 719 1058 pthread_mutex_unlock(&audio_buflock); 720 1059 } 721 1060 … … 728 1067 729 1068 if (source_bitrate == -1) 730 1069 { 1070 #if UPMIXINLOOP 731 1071 source_bitrate = audio_samplerate * audio_channels * audio_bits; 1072 #else 1073 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 1074 #endif 732 1075 } 733 1076 734 1077 if (ct / 1000 != current_seconds) 735 1078 { 736 1079 current_seconds = ct / 1000; 1080 #if UPMIXINLOOP 737 1081 OutputEvent e(current_seconds, ct, 738 1082 source_bitrate, audio_samplerate, audio_bits, 739 1083 audio_channels); 1084 #else 1085 OutputEvent e(current_seconds, ct, 1086 source_bitrate, audio_samplerate, audio_bits, 1087 source_audio_channels); 1088 #endif 740 1089 dispatch(e); 741 1090 } 742 1091 } … … 769 1118 space_on_soundcard = getSpaceOnSoundcard(); 770 1119 771 1120 if (space_on_soundcard != last_space_on_soundcard) { 772 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1121 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 773 1122 .arg(space_on_soundcard)); 774 1123 last_space_on_soundcard = space_on_soundcard; 775 1124 } … … 782 1131 WriteAudio(zeros, fragment_size); 783 1132 } else { 784 1133 // this should never happen now -dag 785 VERBOSE(VB_AUDIO , LOC +1134 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 786 1135 QString("waiting for space on soundcard " 787 1136 "to write zeros: have %1 need %2") 788 1137 .arg(space_on_soundcard).arg(fragment_size)); … … 818 1167 if (fragment_size > audiolen(true)) 819 1168 { 820 1169 if (audiolen(true) > 0) // only log if we're sending some audio 821 VERBOSE(VB_AUDIO , LOC +1170 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 822 1171 QString("audio waiting for buffer to fill: " 823 1172 "have %1 want %2") 824 1173 .arg(audiolen(true)).arg(fragment_size)); 825 1174 826 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1175 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 827 1176 pthread_mutex_lock(&audio_buflock); 828 1177 pthread_cond_broadcast(&audio_bufsig); 829 1178 pthread_mutex_unlock(&audio_buflock); … … 837 1186 if (fragment_size > space_on_soundcard) 838 1187 { 839 1188 if (space_on_soundcard != last_space_on_soundcard) { 840 VERBOSE(VB_AUDIO , LOC +1189 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 841 1190 QString("audio waiting for space on soundcard: " 842 1191 "have %1 need %2") 843 1192 .arg(space_on_soundcard).arg(fragment_size)); … … 899 1248 900 1249 /* update raud */ 901 1250 raud = (raud + fragment_size) % AUDBUFSIZE; 902 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1251 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 903 1252 pthread_cond_broadcast(&audio_bufsig); 904 1253 905 1254 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"), "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 98 static HostComboBox *AudioUpmixType() 99 { 100 HostComboBox *gc = new HostComboBox("AudioUpmixType",false); 101 gc->setLabel(QObject::tr("Upmix")); 102 gc->addSelection(QObject::tr("Passive"), "0"); 103 gc->addSelection(QObject::tr("Active Simple"), "1"); 104 gc->addSelection(QObject::tr("Active Linear"), "2", true); // default 105 gc->setHelpText( 106 QObject::tr("Set the audio upmix type for 2ch to 6ch conversion. " 107 "This is for multi-channel/surround audio playback.")); 108 return gc; 109 } 110 81 111 static HostComboBox *PassThroughOutputDevice() 82 112 { 83 113 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3145 3175 vgrp0->addChild(AC3PassThrough()); 3146 3176 vgrp0->addChild(DTSPassThrough()); 3147 3177 3178 HorizontalConfigurationGroup *agrp = 3179 new HorizontalConfigurationGroup(false, false, true, true); 3180 agrp->addChild(MaxAudioChannels()); 3181 agrp->addChild(AudioUpmixType()); 3182 addChild(agrp); 3183 3148 3184 VerticalConfigurationGroup *vgrp1 = 3149 3185 new VerticalConfigurationGroup(false, false, true, true); 3150 3186 vgrp1->addChild(AggressiveBuffer()); -
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;