Ticket #1104: mythtv_ac3.42.patch
| File mythtv_ac3.42.patch, 124.1 KB (added by markspieth, 4 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 const float center_level = sqrt(0.5); // gain of the center channel 35 //const float center_level = 0.5; // gain of the center channel 36 37 // should be .6-.7 38 // but with centerlevel 2x what its supposed to be, we halve 0.68 39 // to keep center from clipping 40 const float window_gain = 0.34; 41 42 // private implementation of the surround decoder 43 class decoder_impl { 44 public: 45 // create an instance of the decoder 46 // blocksize is fixed over the lifetime of this object for performance reasons 47 decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) { 48 // create FFTW buffers 49 lt = (float*)fftwf_malloc(sizeof(float)*N); 50 rt = (float*)fftwf_malloc(sizeof(float)*N); 51 dst = (float*)fftwf_malloc(sizeof(float)*N); 52 dftL = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N); 53 dftR = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N); 54 src = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*N); 55 loadL = fftwf_plan_dft_r2c_1d(N, lt, dftL,FFTW_MEASURE); 56 loadR = fftwf_plan_dft_r2c_1d(N, rt, dftR,FFTW_MEASURE); 57 store = fftwf_plan_dft_c2r_1d(N, src, dst,FFTW_MEASURE); 58 // resize our own buffers 59 frontR.resize(N); 60 frontL.resize(N); 61 avg.resize(N); 62 surR.resize(N); 63 surL.resize(N); 64 #ifdef FILTERED_LFE 65 trueavg.resize(N); 66 #endif 67 xfs.resize(N); 68 yfs.resize(N); 69 inbuf[0].resize(N); 70 inbuf[1].resize(N); 71 for (unsigned c=0;c<6;c++) { 72 outbuf[c].resize(N); 73 filter[c].resize(N); 74 } 75 // DC component of filters is always 0 76 for (unsigned c=0;c<5;c++) 77 { 78 filter[c][0] = 0.0; 79 filter[c][1] = 0.0; 80 filter[c][halfN] = 0.0; 81 } 82 sample_rate(48000); 83 // generate the window function (square root of hann, b/c it is applied before and after the transform) 84 wnd.resize(N); 85 // dft normalization included in the window for zero cost scaling 86 // also add a gain factor of *2 due to processing gain in algo (see center_level) 87 for (unsigned k=0;k<N;k++) 88 //wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N); 89 wnd[k] = sqrt(window_gain*0.5*(1-cos(2*PI*k/N))/N); 90 current_buf = 0; 91 // set the default coefficients 92 surround_coefficients(0.8165,0.5774); 93 phase_mode(0); 94 separation(1,1); 95 steering_mode(1); 96 } 97 98 // destructor 99 ~decoder_impl() { 100 // clean up the FFTW stuff 101 fftwf_destroy_plan(store); 102 fftwf_destroy_plan(loadR); 103 fftwf_destroy_plan(loadL); 104 fftwf_free(src); 105 fftwf_free(dftR); 106 fftwf_free(dftL); 107 fftwf_free(dst); 108 fftwf_free(rt); 109 fftwf_free(lt); 110 } 111 112 float ** getInputBuffers() 113 { 114 inbufs[0] = &inbuf[0][current_buf*halfN]; 115 inbufs[1] = &inbuf[1][current_buf*halfN]; 116 return inbufs; 117 } 118 119 float ** getOutputBuffers() 120 { 121 outbufs[0] = &outbuf[0][current_buf*halfN]; 122 outbufs[1] = &outbuf[1][current_buf*halfN]; 123 outbufs[2] = &outbuf[2][current_buf*halfN]; 124 outbufs[3] = &outbuf[3][current_buf*halfN]; 125 outbufs[4] = &outbuf[4][current_buf*halfN]; 126 outbufs[5] = &outbuf[5][current_buf*halfN]; 127 return outbufs; 128 } 129 130 // decode a chunk of stereo sound, has to contain exactly blocksize samples 131 // center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution 132 // dimension [0..1] moves the soundfield backwards, 0=front, 1=side 133 // adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption 134 void decode(float center_width, float dimension, float adaption_rate) { 135 // process first part 136 int index; 137 index = current_buf*halfN; 138 float *in_second[2] = {&inbuf[0][index],&inbuf[1][index]}; 139 current_buf ^= 1; 140 index = current_buf*halfN; 141 float *in_first[2] = {&inbuf[0][index],&inbuf[1][index]}; 142 add_output(in_first,in_second,center_width,dimension,adaption_rate,true); 143 // shift last half of input buffer to the beginning 144 } 145 146 // flush the internal buffers 147 void flush() { 148 for (unsigned k=0;k<N;k++) { 149 for (unsigned c=0;c<6;c++) 150 outbuf[c][k] = 0; 151 inbuf[0][k] = 0; 152 inbuf[1][k] = 0; 153 } 154 } 155 156 // set lfe filter params 157 void sample_rate(unsigned int srate) { 158 // lfe filter is just straight through band limited 159 unsigned int cutoff = (250*N)/srate; 160 for (unsigned f=0;f<=halfN;f++) { 161 if ((f>=2) && (f<cutoff)) 162 filter[5][f] = 1.0; 163 else 164 filter[5][f] = 0.0; 165 } 166 } 167 168 // set the assumed surround mixing coefficients 169 void surround_coefficients(float a, float b) { 170 master_gain = 1.0; 171 // calc the simple coefficients 172 surround_high = a; 173 surround_low = b; 174 surround_balance = (a-b)/(a+b); 175 surround_level = 1/(a+b); 176 // calc the linear coefficients 177 cfloat i(0,1), u((a+b)*i), v((b-a)*i), n(0.25,0),o(1,0); 178 A = (v-o)*n; B = (o-u)*n; C = (-o-v)*n; D = (o+u)*n; 179 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 180 } 181 182 // set the phase shifting mode 183 void phase_mode(unsigned mode) { 184 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; 185 phase_offsetL = modes[mode][0]; 186 phase_offsetR = modes[mode][1]; 187 } 188 189 // what steering mode should be chosen 190 void steering_mode(bool mode) { linear_steering = mode; } 191 192 // set front & rear separation controls 193 void separation(float front, float rear) { 194 front_separation = front; 195 rear_separation = rear; 196 } 197 198 private: 199 // polar <-> cartesian coodinates conversion 200 static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); } 201 static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); } 202 static inline cfloat polar(float a, float p) { return cfloat(a*cos(p),a*sin(p)); } 203 static inline float sqr(float x) { return x*x; } 204 // the dreaded min/max 205 static inline float min(float a, float b) { return a<b?a:b; } 206 static inline float max(float a, float b) { return a>b?a:b; } 207 static inline float clamp(float x) { return max(-1,min(1,x)); } 208 209 // handle the output buffering for overlapped calls of block_decode 210 void add_output(float *input1[2], float *input2[2], float center_width, float dimension, float adaption_rate, bool result=false) { 211 // add the windowed data to the last 1/2 of the output buffer 212 float *out[6] = {&outbuf[0][0],&outbuf[1][0],&outbuf[2][0],&outbuf[3][0],&outbuf[4][0],&outbuf[5][0]}; 213 block_decode(input1,input2,out,center_width,dimension,adaption_rate); 214 } 215 216 // CORE FUNCTION: decode a block of data 217 void block_decode(float *input1[2], float *input2[2], float *output[6], float center_width, float dimension, float adaption_rate) { 218 // 1. scale the input by the window function; this serves a dual purpose: 219 // - first it improves the FFT resolution b/c boundary discontinuities (and their frequencies) get removed 220 // - second it allows for smooth blending of varying filters between the blocks 221 { 222 float* pWnd = &wnd[0]; 223 float* pLt = <[0]; 224 float* pRt = &rt[0]; 225 float* pIn0 = input1[0]; 226 float* pIn1 = input1[1]; 227 for (unsigned k=0;k<halfN;k++) { 228 *pLt++ = *pIn0++ * *pWnd; 229 *pRt++ = *pIn1++ * *pWnd++; 230 } 231 pIn0 = input2[0]; 232 pIn1 = input2[1]; 233 //for (unsigned k=0,k1=halfN;k<halfN;k++,k1++) { 234 for (unsigned k=0;k<halfN;k++) { 235 *pLt++ = *pIn0++ * *pWnd; 236 *pRt++ = *pIn1++ * *pWnd++; 237 } 238 } 239 240 // ... and tranform it into the frequency domain 241 fftwf_execute(loadL); 242 fftwf_execute(loadR); 243 244 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 245 // but dont do DC or N/2 component 246 for (unsigned f=2;f<halfN;f++) { 247 // get left/right amplitudes/phases 248 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 249 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); 250 // if (ampL+ampR < epsilon) 251 // continue; 252 253 // calculate the amplitude/phase difference 254 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 255 float phaseDiff = phaseL - phaseR; 256 if (phaseDiff < -PI) phaseDiff += 2*PI; 257 if (phaseDiff > PI) phaseDiff -= 2*PI; 258 phaseDiff = abs(phaseDiff); 259 260 if (linear_steering) { 261 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2); 262 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */ 263 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real(); 264 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G); 265 266 /* 267 Problem: 268 This assumes that the values are interpolated linearly between the cardinal points. 269 But this way we have no chance of knowing the average volume... 270 - Can we solve that computing everything under the assumption of normalized volume? 271 No. Seemingly not. 272 - Maybe we should add w explitcitly into the equation and see if we can solve it... 273 */ 274 275 276 //cfloat lt(0.5,0),rt(0.5,0); 277 //cfloat x(0,0), y(1,0); 278 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E); 279 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E); 280 cfloat s = sqrt(p*p/4.0f - q); 281 cfloat x = -p; 282 cfloat x1 = -p/2.0f + s; 283 cfloat x2 = -p/2.0f - s; 284 float x = 0; 285 if (x1.real() >= -1 && x1.real() <= 1) 286 x = x1.real(); 287 else if (x2.real() >= -1 && x2.real() <= 1) 288 x = x2.real();*/ 289 290 //cfloat yp = (rt - (x*E+H))/(F+x*G); 291 //cfloat xp = (lt - (y*B+D))/(A+y*C); 292 293 /*xfs[f] = x; 294 yfs[f] = y.real();*/ 295 296 // --- this is the fancy new linear mode --- 297 298 // get sound field x/y position 299 yfs[f] = get_yfs(ampDiff,phaseDiff); 300 xfs[f] = get_xfs(ampDiff,yfs[f]); 301 302 // add dimension control 303 yfs[f] = clamp(yfs[f] - dimension); 304 305 // add crossfeed control 306 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 307 308 // 3. generate frequency filters for each output channel 309 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 310 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 311 float volume[5] = { 312 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 313 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 314 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 315 back * surround_level * left, // left surround 316 back * surround_level * right // right surround 317 }; 318 319 // adapt the prior filter 320 for (unsigned c=0;c<5;c++) 321 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/*/N*/; 322 323 } else { 324 // --- this is the old & simple steering mode --- 325 326 // calculate the amplitude/phase difference 327 float ampDiff = clamp((ampL+ampR < epsilon) ? 0 : (ampR-ampL) / (ampR+ampL)); 328 float phaseDiff = phaseL - phaseR; 329 if (phaseDiff < -PI) phaseDiff += 2*PI; 330 if (phaseDiff > PI) phaseDiff -= 2*PI; 331 phaseDiff = abs(phaseDiff); 332 333 // determine sound field x-position 334 xfs[f] = ampDiff; 335 336 // determine preliminary sound field y-position from phase difference 337 yfs[f] = 1 - (phaseDiff/PI)*2; 338 339 if (abs(xfs[f]) > surround_balance) { 340 // blend linearly between the surrounds and the fronts if the balance exceeds the surround encoding balance 341 // this is necessary because the sound field is trapezoidal and will be stretched behind the listener 342 float frontness = (abs(xfs[f]) - surround_balance)/(1-surround_balance); 343 yfs[f] = (1-frontness) * yfs[f] + frontness * 1; 344 } 345 346 // add dimension control 347 yfs[f] = clamp(yfs[f] - dimension); 348 349 // add crossfeed control 350 xfs[f] = clamp(xfs[f] * (front_separation*(1+yfs[f])/2 + rear_separation*(1-yfs[f])/2)); 351 352 // 3. generate frequency filters for each output channel, according to the signal position 353 // the sum of all channel volumes must be 1.0 354 float left = (1-xfs[f])/2, right = (1+xfs[f])/2; 355 float front = (1+yfs[f])/2, back = (1-yfs[f])/2; 356 float volume[5] = { 357 front * (left * center_width + max(0,-xfs[f]) * (1-center_width)), // left 358 front * center_level*((1-abs(xfs[f])) * (1-center_width)), // center 359 front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right 360 back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))), // left surround 361 back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2))) // right surround 362 }; 363 364 // adapt the prior filter 365 for (unsigned c=0;c<5;c++) 366 filter[c][f] = (1-adaption_rate)*filter[c][f] + adaption_rate*volume[c]/*/N*/; 367 } 368 369 // ... and build the signal which we want to position 370 frontL[f] = polar(ampL+ampR,phaseL); 371 frontR[f] = polar(ampL+ampR,phaseR); 372 avg[f] = frontL[f] + frontR[f]; 373 surL[f] = polar(ampL+ampR,phaseL+phase_offsetL); 374 surR[f] = polar(ampL+ampR,phaseR+phase_offsetR); 375 #ifdef FILTERED_LFE 376 trueavg[f] = cfloat(dftL[f][0] + dftR[f][0], dftL[f][1] + dftR[f][1]); 377 #endif 378 } 379 380 // 4. distribute the unfiltered reference signals over the channels 381 apply_filter(&frontL[0],&filter[0][0],&output[0][0]); // front left 382 apply_filter(&avg[0], &filter[1][0],&output[1][0]); // front center 383 apply_filter(&frontR[0],&filter[2][0],&output[2][0]); // front right 384 apply_filter(&surL[0],&filter[3][0],&output[3][0]); // surround left 385 apply_filter(&surR[0],&filter[4][0],&output[4][0]); // surround right 386 #ifdef FILTERED_LFE 387 apply_filter(&trueavg[0],&filter[5][0],&output[5][0]); // lfe 388 #else 389 float* out5 = &output[5][(current_buf)*halfN]; 390 float* in2l = &input2[0][0]; 391 float* in2r = &input2[1][0]; 392 //for (unsigned k=0,k2=N/4;k<halfN;k++,k2++) { 393 for (unsigned k=0;k<halfN;k++) { 394 *out5++ = *in2l++ + *in2r++; 395 } 396 #endif 397 } 398 399 #define FASTER_CALC 400 // map from amplitude difference and phase difference to yfs 401 inline double get_yfs(double ampDiff, double phaseDiff) { 402 double x = 1-(((1-sqr(ampDiff))*phaseDiff)/PI*2); 403 #ifdef FASTER_CALC 404 double tanX = tan(x); 405 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 406 + 0.09170680403453149*x*x*x + 0.2617754892323973*tanX - 0.04180413533856156*sqr(tanX); 407 #else 408 return 0.16468622925824683 + 0.5009268347818189*x - 0.06462757726992101*x*x 409 + 0.09170680403453149*x*x*x + 0.2617754892323973*tan(x) - 0.04180413533856156*sqr(tan(x)); 410 #endif 411 } 412 413 // map from amplitude difference and yfs to xfs 414 inline double get_xfs(double ampDiff, double yfs) { 415 double x=ampDiff,y=yfs; 416 #ifdef FASTER_CALC 417 double tanX = tan(x); 418 double tanY = tan(y); 419 double asinX = asin(x); 420 double sinX = sin(x); 421 double sinY = sin(y); 422 double x3 = x*x*x; 423 double y2 = y*y; 424 double y3 = y*y2; 425 return 2.464833559224702*x - 423.52131153259404*x*y + 426 67.8557858606918*x3*y + 788.2429425544392*x*y2 - 427 79.97650354902909*x3*y2 - 513.8966153850349*x*y3 + 428 35.68117670186306*x3*y3 + 13867.406173420834*y*asinX - 429 2075.8237075786396*y2*asinX - 908.2722068360281*y3*asinX - 430 12934.654772878019*asinX*sinY - 13216.736529661162*y*tanX + 431 1288.6463247741938*y2*tanX + 1384.372969378453*y3*tanX + 432 12699.231471126128*sinY*tanX + 95.37131275594336*sinX*tanY - 433 91.21223198407546*tanX*tanY; 434 #else 435 return 2.464833559224702*x - 423.52131153259404*x*y + 436 67.8557858606918*x*x*x*y + 788.2429425544392*x*y*y - 437 79.97650354902909*x*x*x*y*y - 513.8966153850349*x*y*y*y + 438 35.68117670186306*x*x*x*y*y*y + 13867.406173420834*y*asin(x) - 439 2075.8237075786396*y*y*asin(x) - 908.2722068360281*y*y*y*asin(x) - 440 12934.654772878019*asin(x)*sin(y) - 13216.736529661162*y*tan(x) + 441 1288.6463247741938*y*y*tan(x) + 1384.372969378453*y*y*y*tan(x) + 442 12699.231471126128*sin(y)*tan(x) + 95.37131275594336*sin(x)*tan(y) - 443 91.21223198407546*tan(x)*tan(y); 444 #endif 445 } 446 447 // filter the complex source signal and add it to target 448 void apply_filter(cfloat *signal, float *flt, float *target) { 449 // filter the signal 450 for (unsigned f=0;f<=halfN;f++) { 451 src[f][0] = signal[f].real() * flt[f]; 452 src[f][1] = signal[f].imag() * flt[f]; 453 } 454 // transform into time domain 455 fftwf_execute(store); 456 457 float* pT1 = &target[current_buf*halfN]; 458 float* pWnd1 = &wnd[0]; 459 float* pDst1 = &dst[0]; 460 float* pT2 = &target[(current_buf^1)*halfN]; 461 float* pWnd2 = &wnd[halfN]; 462 float* pDst2 = &dst[halfN]; 463 // add the result to target, windowed 464 for (unsigned int k=0;k<halfN;k++) 465 { 466 // 1st part is overlap add 467 *pT1++ += *pWnd1++ * *pDst1++; 468 // 2nd part is set as has no history 469 *pT2++ = *pWnd2++ * *pDst2++; 470 } 471 } 472 473 unsigned int N; // the block size 474 unsigned int halfN; // half block size precalculated 475 // FFTW data structures 476 float *lt,*rt,*dst; // left total, right total (source arrays), destination array 477 fftwf_complex *dftL,*dftR,*src; // intermediate arrays (FFTs of lt & rt, processing source) 478 fftwf_plan loadL,loadR,store; // plans for loading the data into the intermediate format and back 479 // buffers 480 std::vector<cfloat> frontL,frontR,avg,surL,surR; // the signal (phase-corrected) in the frequency domain 481 #ifdef FILTERED_LFE 482 std::vector<cfloat> trueavg; // for lfe generation 483 #endif 484 std::vector<float> xfs,yfs; // the feature space positions for each frequency bin 485 std::vector<float> wnd; // the window function, precalculated 486 std::vector<float> filter[6]; // a frequency filter for each output channel 487 std::vector<float> inbuf[2]; // the sliding input buffers 488 std::vector<float> outbuf[6]; // the sliding output buffers 489 // coefficients 490 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 491 float surround_balance; // the xfs balance that follows from the coeffs 492 float surround_level; // gain for the surround channels (follows from the coeffs 493 float master_gain; // gain for all channels 494 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 495 float front_separation; // front stereo separation 496 float rear_separation; // rear stereo separation 497 bool linear_steering; // whether the steering should be linear or not 498 cfloat A,B,C,D,E,F,G,H; // coefficients for the linear steering 499 int current_buf; // specifies which buffer is 2nd half of input sliding buffer 500 float * inbufs[2]; // for passing back to driver 501 float * outbufs[6]; // for passing back to driver 502 503 friend class fsurround_decoder; 504 }; 505 506 507 // implementation of the shell class 508 509 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { } 510 511 fsurround_decoder::~fsurround_decoder() { delete impl; } 512 513 void fsurround_decoder::decode(float center_width, float dimension, float adaption_rate) { 514 impl->decode(center_width,dimension,adaption_rate); 515 } 516 517 void fsurround_decoder::flush() { impl->flush(); } 518 519 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 520 521 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 522 523 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); } 524 525 void fsurround_decoder::separation(float front, float rear) { impl->separation(front,rear); } 526 527 float ** fsurround_decoder::getInputBuffers() 528 { 529 return impl->getInputBuffers(); 530 } 531 532 float ** fsurround_decoder::getOutputBuffers() 533 { 534 return impl->getOutputBuffers(); 535 } 536 537 void fsurround_decoder::sample_rate(unsigned int samplerate) 538 { 539 impl->sample_rate(samplerate); 540 } -
libs/libmythfreesurround/el_processor.h
1 /* 2 Copyright (C) 2007 Christian Kothe 3 4 This program is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public License 6 as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19 #ifndef EL_PROCESSOR_H 20 #define EL_PROCESSOR_H 21 22 // the Free Surround decoder 23 class fsurround_decoder { 24 public: 25 // create an instance of the decoder 26 // blocksize is fixed over the lifetime of this object for performance reasons 27 fsurround_decoder(unsigned blocksize=8192); 28 // destructor 29 ~fsurround_decoder(); 30 31 float ** getInputBuffers(); 32 float ** getOutputBuffers(); 33 34 // decode a chunk of stereo sound, has to contain exactly blocksize samples 35 // center_width [0..1] distributes the center information towards the front left/right channels, 1=full distribution, 0=no distribution 36 // dimension [0..1] moves the soundfield backwards, 0=front, 1=side 37 // adaption_rate [0..1] determines how fast the steering gets adapted, 1=instantaneous, 0.1 = very slow adaption 38 //void decode(float *input[2], float *output[6], float center_width=1, float dimension=0, float adaption_rate=1); 39 void decode(float center_width=1, float dimension=0, float adaption_rate=1); 40 41 // flush the internal buffers 42 void flush(); 43 44 // --- advanced configuration --- 45 46 // override the surround coefficients 47 // 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. 48 void surround_coefficients(float a, float b); 49 50 // set the phase shifting mode for decoding 51 // 0 = (+0°,+0°) - music mode 52 // 1 = (+0°,+180°) - PowerDVD compatibility 53 // 2 = (+180°,+0°) - BeSweet compatibility 54 // 3 = (-90°,+90°) - This seems to work. I just don't know why. 55 void phase_mode(unsigned mode); 56 57 // override the steering mode 58 // false = simple non-linear steering (old) 59 // true = advanced linear steering (new) 60 void steering_mode(bool mode); 61 62 // set front/rear stereo separation 63 // 1.0 is default, 0.0 is mono 64 void separation(float front,float rear); 65 66 // set samplerate for lfe filter 67 void sample_rate(unsigned int samplerate); 68 69 private: 70 class decoder_impl *impl; // private implementation (details hidden) 71 }; 72 73 74 #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; 66 //#define MASTER_GAIN * master_gain 67 #define MASTER_GAIN 68 //const float master_gain = 1.0/(1<<15); 69 //const float inv_master_gain = (1<<15); 70 //#define INV_MASTER_GAIN * inv_master_gain 71 #define INV_MASTER_GAIN 72 73 unsigned int block_size = default_block_size; 74 75 // stupidity countermeasure... 76 template<class T> T pop_back(std::list<T> &l) 77 { 78 T result(l.back()); 79 l.pop_back(); 80 return result; 81 } 82 83 // a pool, where the DSP can throw its objects at after it got deleted and get them back when it is recreated... 84 class object_pool 85 { 86 public: 87 typedef void* (*callback)(); 88 // initialize 89 object_pool(callback cbf):construct(cbf) { } 90 ~object_pool() 91 { 92 for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();i!=e;i++) 93 delete i->second; 94 for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();i!=e;i++) 95 delete *i; 96 } 97 // (re)acquire an object 98 void *acquire(void *who) 99 { 100 std::map<void*,void*>::iterator i(pool.find(who)); 101 if (i != pool.end()) 102 return i->second; 103 else 104 if (!freelist.empty()) 105 return pool.insert(std::make_pair(who,pop_back(freelist))).first->second; 106 else 107 return pool.insert(std::make_pair(who,construct())).first->second; 108 } 109 // release an object into the wild 110 void release(void *who) 111 { 112 std::map<void*,void*>::iterator i(pool.find(who)); 113 if (i != pool.end()) { 114 freelist.push_back(i->second); 115 pool.erase(i); 116 } 117 } 118 public: 119 callback construct; // object constructor callback 120 std::list<void*> freelist; // list of available objects 121 std::map<void*,void*> pool; // pool of used objects, by class 122 }; 123 124 // buffers which we usually need (and want to share between plugin lifespans) 125 struct buffers 126 { 127 buffers(unsigned int s): 128 //lt(s),rt(s), 129 l(s),r(s),c(s),ls(s),rs(s),lfe(s) { } 130 void resize(unsigned int s) 131 { 132 //lt.resize(s); rt.resize(s); 133 l.resize(s); r.resize(s); lfe.resize(s); 134 ls.resize(s); rs.resize(s); c.resize(s); 135 } 136 void clear() 137 { 138 //lt.clear(); rt.clear(); 139 l.clear(); r.clear(); lfe.clear(); 140 ls.clear(); rs.clear(); c.clear(); 141 } 142 //std::vector<float> lt,rt; // for multiplexing 143 std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs; // for demultiplexing 144 }; 145 146 struct int16buffers 147 { 148 int16buffers(unsigned int s): 149 l(s),r(s),c(s),ls(s),rs(s),lfe(s) { } 150 void resize(unsigned int s) 151 { 152 l.resize(s); r.resize(s); lfe.resize(s); 153 ls.resize(s); rs.resize(s); c.resize(s); 154 } 155 void clear() 156 { 157 l.clear(); r.clear(); 158 ls.clear(); rs.clear(); c.clear(); 159 lfe.clear(); 160 } 161 std::vector<short> l,r,c,ls,rs,lfe; // for demultiplexing 162 }; 163 164 // construction methods 165 void *new_decoder() { return new fsurround_decoder(block_size); } 166 void *new_buffers() { return new buffers(block_size/2); } 167 void *new_int16buffers() { return new int16buffers(block_size/2); } 168 169 object_pool dp(&new_decoder); 170 //object_pool bp(&new_buffers); 171 object_pool bp16(&new_int16buffers); 172 173 //#define SPEAKERTEST 174 #ifdef SPEAKERTEST 175 int channel_select = -1; 176 #endif 177 178 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) : 179 srate(srate), 180 open_(false), 181 initialized_(false), 182 //bufs(NULL), 183 int16bufs(NULL), 184 decoder(0), 185 in_count(0), 186 out_count(0), 187 processed(true), 188 surround_mode(smode) 189 { 190 VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode)); 191 if (moviemode) 192 { 193 params.phasemode = 1; 194 params.center_width = 0; 195 } 196 else 197 { 198 params.center_width = 50; 199 } 200 switch (surround_mode) 201 { 202 case SurroundModeActiveSimple: 203 params.steering = 0; 204 //bufs = (buffers*)bp.acquire((void*)1); 205 break; 206 case SurroundModeActiveLinear: 207 params.steering = 1; 208 //bufs = (buffers*)bp.acquire((void*)1); 209 break; 210 default: 211 //int16bufs = (int16buffers*)bp16.acquire((void*)1); 212 break; 213 } 214 int16bufs = (int16buffers*)bp16.acquire((void*)1); 215 open(); 216 #ifdef SPEAKERTEST 217 channel_select++; 218 if (channel_select>=6) 219 channel_select = 0; 220 VERBOSE(QString("FreeSurround::FreeSurround channel_select %1").arg(channel_select)); 221 #endif 222 223 VERBOSE(QString("FreeSurround::FreeSurround done")); 224 } 225 226 void FreeSurround::SetParams() 227 { 228 if (decoder) 229 { 230 decoder->steering_mode(params.steering); 231 decoder->phase_mode(params.phasemode); 232 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 233 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 234 } 235 } 236 237 FreeSurround::fsurround_params::fsurround_params( 238 int32_t center_width, 239 int32_t dimension 240 ) : 241 center_width(center_width), 242 dimension(dimension), 243 coeff_a(0.8165),coeff_b(0.5774), 244 phasemode(0), 245 steering(1), 246 front_sep(100), 247 rear_sep(100) 248 { 249 } 250 251 FreeSurround::~FreeSurround() 252 { 253 VERBOSE(QString("FreeSurround::~FreeSurround")); 254 close(); 255 /* 256 if (bufs) 257 { 258 bp.release((void*)1); 259 bufs = NULL; 260 } 261 */ 262 if (int16bufs) 263 { 264 bp16.release((void*)1); 265 int16bufs = NULL; 266 } 267 VERBOSE(QString("FreeSurround::~FreeSurround done")); 268 } 269 270 void get_peak_i(short* data, int count, int* maxv, int* minv) 271 { 272 int _maxv = *data++; 273 int _minv = _maxv; 274 for(int i=1;i<count;i++) 275 { 276 int v = *data++; 277 if (v > _maxv) _maxv = v; 278 if (v < _minv) _minv = v; 279 } 280 *maxv = _maxv; 281 *minv = _minv; 282 } 283 284 void get_peak_i2(short* data, int count, int* maxv, int* minv) 285 { 286 int _maxv = *data; 287 data += 2; 288 int _minv = _maxv; 289 for(int i=1;i<count;i++) 290 { 291 int v = *data; 292 if (v > _maxv) _maxv = v; 293 if (v < _minv) _minv = v; 294 data += 2; 295 } 296 *maxv = _maxv; 297 *minv = _minv; 298 } 299 300 void get_peak(float* data, int count, int* maxv, int* minv) 301 { 302 int _maxv = lrintf(*data++); 303 int _minv = _maxv; 304 for(int i=1;i<count;i++) 305 { 306 int v = lrintf(*data++); 307 if (v > _maxv) _maxv = v; 308 if (v < _minv) _minv = v; 309 } 310 *maxv = _maxv; 311 *minv = _minv; 312 } 313 314 uint FreeSurround::putSamples(short* samples, uint numSamples, uint numChannels, int step) 315 { 316 int i; 317 int ic = in_count; 318 int bs = block_size/2; 319 bool process = true; 320 // demultiplex 321 switch (surround_mode) 322 { 323 case SurroundModePassive: 324 switch (numChannels) 325 { 326 case 1: 327 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 328 { 329 int16bufs->l[ic] = 330 int16bufs->c[ic] = 331 int16bufs->r[ic] = 332 samples[i] >> 1; 333 } 334 break; 335 case 2: 336 if (step>0) 337 { 338 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 339 { 340 short lt = samples[i] >> 1; 341 short rt = samples[i+step] >> 1; 342 int16bufs->l[ic] = lt; 343 int16bufs->lfe[ic] = 344 int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5) 345 int16bufs->r[ic] = rt; 346 int16bufs->ls[ic] = 347 int16bufs->rs[ic] = ((lt-rt)*23)>>5; 348 } 349 } 350 else 351 { 352 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 353 { 354 short lt = samples[i*2] >> 1; 355 short rt = samples[i*2+1] >> 1; 356 int16bufs->l[ic] = lt; 357 int16bufs->lfe[ic] = 358 int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5) 359 int16bufs->r[ic] = rt; 360 int16bufs->ls[ic] = 361 int16bufs->rs[ic] = ((lt-rt)*23)>>5; 362 } 363 } 364 break; 365 case 6: 366 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 367 { 368 int16bufs->l[ic] = *samples++ >> 1; 369 int16bufs->c[ic] = *samples++ >> 1; 370 int16bufs->r[ic] = *samples++ >> 1; 371 int16bufs->ls[ic] = *samples++ >> 1; 372 int16bufs->rs[ic] = *samples++ >> 1; 373 int16bufs->lfe[ic] = *samples++ >> 1; 374 } 375 break; 376 } 377 in_count = 0; 378 out_count = ic; 379 processed_size = ic; 380 processed = false; 381 break; 382 383 default: 384 { 385 float** inputs = decoder->getInputBuffers(); 386 float * lt = &inputs[0][ic]; 387 float * rt = &inputs[1][ic]; 388 if ((ic+numSamples) > bs) 389 numSamples = bs - ic; 390 switch (numChannels) 391 { 392 case 1: 393 for (i=0;i<numSamples;i++) 394 { 395 *lt++ = 396 *rt++ = 397 *samples++ MASTER_GAIN; 398 } 399 break; 400 case 2: 401 if (step>0) 402 { 403 for (i=0;i<numSamples;i++) 404 { 405 *lt++ = samples[0] MASTER_GAIN; 406 *rt++ = samples[step] MASTER_GAIN; 407 samples++; 408 } 409 } 410 else 411 { 412 for (i=0;i<numSamples;i++) 413 { 414 *lt++ = *samples++ MASTER_GAIN; 415 *rt++ = *samples++ MASTER_GAIN; 416 } 417 } 418 break; 419 case 6: 420 { 421 process = false; 422 short * l = &int16bufs->l[ic]; 423 short * c = &int16bufs->c[ic]; 424 short * r = &int16bufs->r[ic]; 425 short * ls = &int16bufs->ls[ic]; 426 short * rs = &int16bufs->rs[ic]; 427 short * lfe = &int16bufs->lfe[ic]; 428 for (i=0;i<numSamples;i++) 429 { 430 *l++ = *samples++ >> 1; 431 *c++ = *samples++ >> 1; 432 *r++ = *samples++ >> 1; 433 *ls++ = *samples++ >> 1; 434 *rs++ = *samples++ >> 1; 435 *lfe++ = *samples++ >> 1; 436 } 437 } break; 438 } 439 ic += numSamples; 440 in_count = ic; 441 processed = process; 442 if (ic == bs) 443 { 444 in_count = 0; 445 if (process) 446 { 447 process_block(); 448 } 449 out_count = bs; 450 processed_size = bs; 451 } 452 } break; 453 } 454 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 455 .arg(numSamples) 456 .arg(numChannels) 457 .arg(step) 458 .arg(i) 459 .arg(out_count) 460 ); 461 return i; 462 } 463 464 uint FreeSurround::putSamples(char* samples, uint numSamples, uint numChannels, int step) 465 { 466 int i; 467 int ic = in_count; 468 int bs = block_size/2; 469 bool process = true; 470 // demultiplex 471 switch (surround_mode) 472 { 473 case SurroundModePassive: 474 switch (numChannels) 475 { 476 case 1: 477 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 478 { 479 int16bufs->l[ic] = 480 int16bufs->c[ic] = 481 int16bufs->r[ic] = 482 samples[i] << 7; 483 } 484 break; 485 case 2: 486 if (step>0) 487 { 488 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 489 { 490 short lt = samples[i] << 7; 491 short rt = samples[i+step] << 7; 492 int16bufs->l[ic] = lt; 493 int16bufs->lfe[ic] = 494 int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5) 495 int16bufs->r[ic] = rt; 496 int16bufs->ls[ic] = 497 int16bufs->rs[ic] = ((lt-rt)*23)>>5; 498 } 499 } 500 else 501 { 502 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 503 { 504 short lt = samples[i*2] << 7; 505 short rt = samples[i*2+1] << 7; 506 int16bufs->l[ic] = lt; 507 int16bufs->lfe[ic] = 508 int16bufs->c[ic] = ((lt+rt)*23)>>5; // about sqrt(0.5) 509 int16bufs->r[ic] = rt; 510 int16bufs->ls[ic] = 511 int16bufs->rs[ic] = ((lt-rt)*23)>>5; 512 } 513 } 514 break; 515 case 6: 516 for (i=0;(i<numSamples) && (ic < bs);i++,ic++) 517 { 518 int16bufs->l[ic] = *samples++ << 7; 519 int16bufs->c[ic] = *samples++ << 7; 520 int16bufs->r[ic] = *samples++ << 7; 521 int16bufs->ls[ic] = *samples++ << 7; 522 int16bufs->rs[ic] = *samples++ << 7; 523 int16bufs->lfe[ic] = *samples++ << 7; 524 } 525 break; 526 } 527 in_count = 0; 528 out_count = ic; 529 processed_size = ic; 530 processed = false; 531 break; 532 533 default: 534 { 535 float** inputs = decoder->getInputBuffers(); 536 float * lt = &inputs[0][ic]; 537 float * rt = &inputs[1][ic]; 538 if ((ic+numSamples) > bs) 539 numSamples = bs - ic; 540 switch (numChannels) 541 { 542 case 1: 543 for (i=0;i<numSamples;i++) 544 { 545 *lt++ = 546 *rt++ = 547 *samples++ MASTER_GAIN; 548 } 549 break; 550 case 2: 551 if (step>0) 552 { 553 for (i=0;i<numSamples;i++) 554 { 555 *lt++ = samples[0] MASTER_GAIN; 556 *rt++ = samples[step] MASTER_GAIN; 557 samples++; 558 } 559 } 560 else 561 { 562 for (i=0;i<numSamples;i++) 563 { 564 *lt++ = *samples++ MASTER_GAIN; 565 *rt++ = *samples++ MASTER_GAIN; 566 } 567 } 568 break; 569 case 6: 570 { 571 process = false; 572 short * l = &int16bufs->l[ic]; 573 short * c = &int16bufs->c[ic]; 574 short * r = &int16bufs->r[ic]; 575 short * ls = &int16bufs->ls[ic]; 576 short * rs = &int16bufs->rs[ic]; 577 short * lfe = &int16bufs->lfe[ic]; 578 for (i=0;i<numSamples;i++) 579 { 580 *l++ = *samples++ << 7; 581 *c++ = *samples++ << 7; 582 *r++ = *samples++ << 7; 583 *ls++ = *samples++ << 7; 584 *rs++ = *samples++ << 7; 585 *lfe++ = *samples++ << 7; 586 } 587 } break; 588 } 589 ic += numSamples; 590 in_count = ic; 591 processed = process; 592 if (ic == bs) 593 { 594 in_count = 0; 595 if (process) 596 process_block(); 597 out_count = bs; 598 processed_size = bs; 599 } 600 } break; 601 } 602 VERBOSE1(QString("FreeSurround::putSamples %1 %2 %3 used %4 generated %5") 603 .arg(numSamples) 604 .arg(numChannels) 605 .arg(step) 606 .arg(i) 607 .arg(out_count) 608 ); 609 return i; 610 } 611 612 uint FreeSurround::receiveSamples( 613 short *output, 614 uint maxSamples 615 ) 616 { 617 uint i; 618 uint oc = out_count; 619 if (maxSamples>oc) maxSamples = oc; 620 uint outindex = processed_size - oc; 621 switch (surround_mode) 622 { 623 case SurroundModePassive: 624 for (unsigned int i=0;i<maxSamples;i++) 625 { 626 *output++ = int16bufs->l[outindex]; 627 *output++ = int16bufs->r[outindex]; 628 *output++ = int16bufs->ls[outindex]; 629 *output++ = int16bufs->rs[outindex]; 630 *output++ = int16bufs->c[outindex]; 631 *output++ = int16bufs->lfe[outindex]; 632 oc--; 633 outindex++; 634 } 635 break; 636 637 default: 638 if (processed) 639 { 640 float** outputs = decoder->getOutputBuffers(); 641 float * l = &outputs[0][outindex]; 642 float * c = &outputs[1][outindex]; 643 float * r = &outputs[2][outindex]; 644 float * ls = &outputs[3][outindex]; 645 float * rs = &outputs[4][outindex]; 646 float * lfe = &outputs[5][outindex]; 647 for (unsigned int i=0;i<maxSamples;i++) 648 { 649 *output++ = lrintf(*l++ INV_MASTER_GAIN); 650 *output++ = lrintf(*r++ INV_MASTER_GAIN); 651 *output++ = lrintf(*ls++ INV_MASTER_GAIN); 652 *output++ = lrintf(*rs++ INV_MASTER_GAIN); 653 *output++ = lrintf(*c++ INV_MASTER_GAIN); 654 *output++ = lrintf(*lfe++ INV_MASTER_GAIN); 655 } 656 oc -= maxSamples; 657 outindex += maxSamples; 658 } 659 else 660 { 661 short * l = &int16bufs->l[outindex]; 662 short * c = &int16bufs->c[outindex]; 663 short * r = &int16bufs->r[outindex]; 664 short * ls = &int16bufs->ls[outindex]; 665 short * rs = &int16bufs->rs[outindex]; 666 short * lfe = &int16bufs->lfe[outindex]; 667 for (unsigned int i=0;i<maxSamples;i++) 668 { 669 *output++ = *l++; 670 *output++ = *r++; 671 *output++ = *ls++; 672 *output++ = *rs++; 673 *output++ = *c++; 674 *output++ = *lfe++; 675 } 676 oc -= maxSamples; 677 outindex += maxSamples; 678 } 679 break; 680 } 681 out_count = oc; 682 VERBOSE1(QString("FreeSurround::receiveSamples %1") 683 .arg(maxSamples) 684 ); 685 return maxSamples; 686 } 687 688 void FreeSurround::process_block() 689 { 690 // process the data 691 try 692 { 693 if (decoder) 694 { 695 // actually these params need only be set when they change... but it doesn't hurt 696 #if 0 697 decoder->steering_mode(params.steering); 698 decoder->phase_mode(params.phasemode); 699 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 700 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 701 #endif 702 // decode the bufs->block 703 //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0); 704 //decoder->decode(output,params.center_width/100.0,params.dimension/100.0); 705 decoder->decode(params.center_width/100.0,params.dimension/100.0); 706 } 707 } 708 catch(...) 709 { 710 //throw(std::runtime_error(std::string("error during processing (unsupported input format?)"))); 711 } 712 } 713 714 long long FreeSurround::getLatency() 715 { 716 // returns in usec 717 if (surround_mode == SurroundModePassive) 718 return 0; 719 return decoder ? ((block_size/2 + in_count)*1000000)/(2*srate) : 0; 720 } 721 722 void FreeSurround::flush() 723 { 724 if (decoder) 725 decoder->flush(); 726 int16bufs->clear(); 727 } 728 729 // load the lib and initialize the interface 730 void FreeSurround::open() 731 { 732 if (!decoder) 733 { 734 decoder = (fsurround_decoder*)dp.acquire((void*)1); 735 decoder->flush(); 736 //if (bufs) 737 // bufs->clear(); 738 if (int16bufs) 739 int16bufs->clear(); 740 decoder->sample_rate(srate); 741 } 742 SetParams(); 743 } 744 745 void FreeSurround::close() 746 { 747 if (decoder) 748 { 749 dp.release(this); 750 decoder = 0; 751 } 752 } 753 754 uint FreeSurround::numUnprocessedSamples() 755 { 756 return in_count; 757 } 758 759 uint FreeSurround::numSamples() 760 { 761 return out_count; 762 } 763 764 uint FreeSurround::sampleLatency() 765 { 766 if (processed) 767 return in_count + out_count + (block_size/2); 768 else 769 return in_count + out_count; 770 } 771 772 uint FreeSurround::samplesPerBlock() 773 { 774 return block_size/2; 775 } 776 -
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 void SetParams(); 58 59 private: 60 61 // the changeable parameters 62 struct fsurround_params { 63 int32_t center_width; // presence of the center channel 64 int32_t dimension; // dimension 65 float coeff_a,coeff_b; // surround mixing coefficients 66 int32_t phasemode; // phase shifting mode 67 int32_t steering; // steering mode (0=simple, 1=linear) 68 int32_t front_sep, rear_sep;// front/rear stereo separation 69 70 // (default) constructor 71 fsurround_params(int32_t center_width=100, int32_t dimension=0); 72 } params; 73 74 // additional settings 75 uint srate; 76 77 // info about the current setup 78 bool open_; // whether a stream is currently open 79 bool initialized_; // whether the thing is intialized 80 //struct buffers *bufs; // our buffers 81 struct int16buffers *int16bufs; // our buffers 82 class fsurround_decoder *decoder; // the surround decoder 83 int in_count; // amount in lt,rt 84 int out_count; // amount in output bufs 85 bool processed; // whether processing is enabled or not for latency calc 86 int processed_size; // amount processed 87 SurroundMode surround_mode; // 1 of 3 surround modes supported 88 89 }; 90 91 #endif 92 -
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); 42 virtual float GetStretchFactor(); 38 43 39 44 // do AddSamples calls block? 40 45 virtual void SetBlocking(bool blocking) = 0; … … 74 79 lastError = msg; 75 80 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 76 81 } 82 void ClearError() 83 { lastError = QString::null; }; 77 84 78 85 void Warn(QString msg) 79 86 { -
libs/libmyth/audiooutput.cpp
133 133 { 134 134 } 135 135 136 float AudioOutput::GetStretchFactor() 137 { 138 return 1.0; 139 } 136 140 141 142 -
libs/libmyth/audiooutputdx.h
35 35 /// END HACK HACK HACK HACK 36 36 37 37 virtual void Reset(void); 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, int audio_passthru); 38 virtual void Reconfigure(int audio_bits, 39 int audio_channels, 40 int audio_samplerate, 41 bool audio_passthru, 42 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 40 43 virtual void SetBlocking(bool blocking); 41 44 42 45 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
130 130 // FIXME: kedl: not sure what else could be required here? 131 131 } 132 132 133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 134 int audio_samplerate, int audio_passthru) 133 void AudioOutputDX::Reconfigure(int audio_bits, 134 int audio_channels, 135 int audio_samplerate, 136 int audio_passthru, 137 AudioCodecMode laom 138 ) 135 139 { 136 140 if (dsbuffer) 137 141 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
16 16 // MythTV headers 17 17 #include "audiooutput.h" 18 18 #include "samplerate.h" 19 #include "SoundTouch.h"20 19 21 #define AUDBUFSIZE 768000 20 namespace soundtouch { 21 class SoundTouch; 22 }; 23 class FreeSurround; 24 class AudioOutputDigitalEncoder; 25 struct AVCodecContext; 26 22 27 #define AUDIO_SRC_IN_SIZE 16384 23 28 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 29 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 30 31 //#define AUDBUFSIZE 768000 32 //divisible by 12,10,8,6,4,2 and around 1024000 33 //#define AUDBUFSIZE 1024080 34 #define AUDBUFSIZE 1536000 35 26 36 class AudioOutputBase : public AudioOutput 27 37 { 28 38 public: … … 35 45 virtual ~AudioOutputBase(); 36 46 37 47 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, 50 int audio_samplerate, 51 bool audio_passthru, 52 void* audio_codec = NULL); 40 53 41 54 // do AddSamples calls block? 42 55 virtual void SetBlocking(bool blocking); … … 45 58 virtual void SetEffDsp(int dsprate); 46 59 47 60 virtual void SetStretchFactor(float factor); 61 virtual float GetStretchFactor(); 48 62 49 63 virtual void Reset(void); 50 64 … … 125 139 bool audio_passthru; 126 140 127 141 float audio_stretchfactor; 142 AVCodecContext *audio_codec; 128 143 AudioOutputSource source; 129 144 130 145 bool killaudio; … … 133 148 bool set_initial_vol; 134 149 bool buffer_output_data_for_use; // used by AudioOutputNULL 135 150 151 int configured_audio_channels; 152 136 153 private: 137 154 // resampler 138 155 bool need_resampler; … … 144 161 145 162 // timestretch 146 163 soundtouch::SoundTouch * pSoundStretch; 164 AudioOutputDigitalEncoder * encoder; 165 FreeSurround * upmixer; 147 166 167 int source_audio_channels; 168 int source_audio_bytes_per_sample; 169 bool needs_upmix; 170 int surround_mode; 171 148 172 bool blocking; // do AddSamples calls block? 149 173 150 174 int lastaudiolen; … … 162 186 163 187 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 164 188 'audiotime' and 'audiotime_updated' */ 165 intaudiotime; // timecode of audio leaving the soundcard (same units as189 long long audiotime; // timecode of audio leaving the soundcard (same units as 166 190 // timecodes) ... 167 191 struct timeval audiotime_updated; // ... which was last updated at this time 168 192 169 193 /* Audio circular buffer */ 170 194 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 171 195 int raud, waud; /* read and write positions */ 172 intaudbuf_timecode; /* timecode of audio most recently placed into196 long long audbuf_timecode; /* timecode of audio most recently placed into 173 197 buffer */ 174 198 175 199 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
15 15 16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 #include "audiooutputdigitalencoder.h" 19 #include "SoundTouch.h" 20 #include "freesurround.h" 18 21 #include "compat.h" 19 22 20 23 #define LOC QString("AO: ") … … 36 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 37 40 audio_passthru(false), audio_stretchfactor(1.0f), 38 41 42 audio_codec(NULL), 39 43 source(lsource), killaudio(false), 40 44 41 45 pauseaudio(false), audio_actually_paused(false), … … 47 51 48 52 src_ctx(NULL), 49 53 50 pSoundStretch(NULL), blocking(false), 54 pSoundStretch(NULL), 55 encoder(NULL), 56 upmixer(NULL), 57 source_audio_channels(-1), 58 source_audio_bytes_per_sample(0), 59 needs_upmix(false), 60 surround_mode(FreeSurround::SurroundModePassive), 51 61 62 blocking(false), 63 52 64 lastaudiolen(0), samples_buffered(0), 53 65 54 66 audio_thread_exists(false), … … 71 83 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 84 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 85 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 86 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 87 75 88 // You need to call Reconfigure from your concrete class. 76 89 // Reconfigure(laudio_bits, laudio_channels, … … 111 124 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 125 .arg(audio_stretchfactor)); 113 126 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 127 if (audio_codec) 128 { 129 if (!encoder) 130 { 131 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 132 encoder = new AudioOutputDigitalEncoder(); 133 if (!encoder->Init(audio_codec->codec_id, 134 audio_codec->bit_rate, 135 audio_codec->sample_rate, 136 audio_codec->channels 137 )) 138 { 139 // eeks 140 delete encoder; 141 encoder = NULL; 142 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 143 } 144 } 145 } 146 if (encoder) 147 { 148 pSoundStretch->setSampleRate(audio_codec->sample_rate); 149 pSoundStretch->setChannels(audio_codec->channels); 150 } 151 else 152 { 153 pSoundStretch->setSampleRate(audio_samplerate); 154 pSoundStretch->setChannels(audio_channels); 155 } 116 156 117 157 pSoundStretch->setTempo(audio_stretchfactor); 118 158 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 134 174 pthread_mutex_unlock(&audio_buflock); 135 175 } 136 176 177 float AudioOutputBase::GetStretchFactor() 178 { 179 return audio_stretchfactor; 180 } 181 137 182 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 183 int laudio_samplerate, bool laudio_passthru, 184 void* laudio_codec) 139 185 { 186 int codec_id = CODEC_ID_NONE; 187 int lcodec_id = CODEC_ID_NONE; 188 int lcchannels = 0; 189 int cchannels = 0; 190 int lsource_audio_channels = laudio_channels; 191 bool lneeds_upmix = false; 192 193 if (laudio_codec) 194 { 195 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 196 laudio_bits = 16; 197 laudio_channels = 2; 198 lsource_audio_channels = laudio_channels; 199 laudio_samplerate = 48000; 200 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 201 } 202 if (audio_codec) 203 { 204 codec_id = audio_codec->codec_id; 205 cchannels = ((AVCodecContext*)audio_codec)->channels; 206 } 207 if ((configured_audio_channels == 6) && 208 !(laudio_codec || audio_codec)) 209 { 210 laudio_channels = configured_audio_channels; 211 lneeds_upmix = true; 212 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 213 } 214 ClearError(); 140 215 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 216 laudio_samplerate == audio_samplerate && !need_resampler && 217 laudio_passthru == audio_passthru && 218 lneeds_upmix == needs_upmix && 219 lcodec_id == codec_id && lcchannels == cchannels) 220 { 221 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 222 return; 144 223 } 145 224 KillAudio(); 146 225 147 226 pthread_mutex_lock(&audio_buflock); … … 151 230 waud = raud = 0; 152 231 audio_actually_paused = false; 153 232 233 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 234 audio_channels = laudio_channels; 235 source_audio_channels = lsource_audio_channels; 155 236 audio_bits = laudio_bits; 156 237 audio_samplerate = laudio_samplerate; 238 audio_codec = (AVCodecContext*)laudio_codec; 157 239 audio_passthru = laudio_passthru; 240 needs_upmix = lneeds_upmix; 158 241 if (audio_bits != 8 && audio_bits != 16) 159 242 { 160 243 pthread_mutex_unlock(&avsync_lock); … … 163 246 return; 164 247 } 165 248 audio_bytes_per_sample = audio_channels * audio_bits / 8; 249 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 166 250 167 251 need_resampler = false; 168 252 killaudio = false; … … 172 256 173 257 numlowbuffer = 0; 174 258 259 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 260 .arg(audio_main_device).arg(audio_channels) 261 .arg(source_audio_channels).arg(audio_samplerate)); 262 175 263 // Actually do the device specific open call 176 264 if (!OpenDevice()) 177 265 { 178 266 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 267 pthread_mutex_unlock(&avsync_lock); 180 268 pthread_mutex_unlock(&audio_buflock); 269 if (GetError().isEmpty()) 270 Error("Aborting reconfigure"); 271 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 272 return; 182 273 } 183 274 … … 200 291 current_seconds = -1; 201 292 source_bitrate = -1; 202 293 294 // NOTE: this wont do anything as above samplerate vars are set equal 203 295 // Check if we need the resampler 204 296 if (audio_samplerate != laudio_samplerate) 205 297 { … … 222 314 need_resampler = true; 223 315 } 224 316 317 if (needs_upmix) 318 { 319 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 320 if (configured_audio_channels == 6) 321 { 322 surround_mode = gContext->GetNumSetting("AudioUpmixType", 2); 323 } 324 upmixer = new FreeSurround(audio_samplerate, 325 source == AUDIOOUTPUT_VIDEO, 326 (FreeSurround::SurroundMode)surround_mode); 327 VERBOSE(VB_AUDIO, LOC + QString("create upmixer done with surround mode %1").arg(surround_mode)); 328 } 329 225 330 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 331 .arg(audio_stretchfactor)); 332 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 333 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 227 334 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 335 if (redo_stretch) 230 336 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 337 float laudio_stretchfactor = audio_stretchfactor; 338 delete pSoundStretch; 339 pSoundStretch = NULL; 340 audio_stretchfactor = 0.0; 341 SetStretchFactorLocked(laudio_stretchfactor); 233 342 } 343 else 344 { 345 SetStretchFactorLocked(audio_stretchfactor); 346 if (pSoundStretch) 347 { 348 // if its passthru then we need to reencode 349 if (audio_codec) 350 { 351 if (!encoder) 352 { 353 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 354 encoder = new AudioOutputDigitalEncoder(); 355 if (!encoder->Init(audio_codec->codec_id, 356 audio_codec->bit_rate, 357 audio_codec->sample_rate, 358 audio_codec->channels 359 )) 360 { 361 // eeks 362 delete encoder; 363 encoder = NULL; 364 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 365 } 366 } 367 } 368 if (encoder) 369 { 370 pSoundStretch->setSampleRate(audio_codec->sample_rate); 371 pSoundStretch->setChannels(audio_codec->channels); 372 } 373 else 374 { 375 pSoundStretch->setSampleRate(audio_samplerate); 376 pSoundStretch->setChannels(audio_channels); 377 } 378 } 379 } 234 380 235 381 // Setup visualisations, zero the visualisations buffers 236 382 prepareVisuals(); … … 290 436 pSoundStretch = NULL; 291 437 } 292 438 439 if (encoder) 440 { 441 delete encoder; 442 encoder = NULL; 443 } 444 445 if (upmixer) 446 { 447 delete upmixer; 448 upmixer = NULL; 449 } 450 needs_upmix = false; 451 293 452 CloseDevice(); 294 453 295 454 killAudioLock.unlock(); … … 303 462 304 463 void AudioOutputBase::Pause(bool paused) 305 464 { 465 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 306 466 pauseaudio = paused; 307 467 audio_actually_paused = false; 308 468 } … … 385 545 The reason is that computing 'audiotime' requires acquiring the audio 386 546 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 547 from the audio thread, and then call this from the video thread. */ 388 intret;548 long long ret; 389 549 struct timeval now; 390 550 391 551 if (audiotime == 0) … … 397 557 398 558 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 559 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);560 ret = (long long)(ret * audio_stretchfactor); 401 561 562 #if 1 563 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 564 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 565 .arg(now.tv_sec).arg(now.tv_usec) 566 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 567 .arg(ret) 568 .arg(audiotime) 569 .arg(audio_stretchfactor) 570 ); 571 #endif 572 402 573 ret += audiotime; 403 574 404 575 pthread_mutex_unlock(&avsync_lock); 405 return ret;576 return (int)ret; 406 577 } 407 578 408 579 void AudioOutputBase::SetAudiotime(void) … … 439 610 // include algorithmic latencies 440 611 if (pSoundStretch) 441 612 { 613 // add the effect of any unused but processed samples, AC3 reencode does this 614 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 442 615 // add the effect of unprocessed samples in time stretch algo 443 616 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 617 audio_bytes_per_sample) / audio_stretchfactor); 445 618 } 446 619 620 if (upmixer && needs_upmix) 621 { 622 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 623 } 624 447 625 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 626 (audio_bytes_per_sample * effdspstretched)); 449 627 450 628 gettimeofday(&audiotime_updated, NULL); 629 #if 1 630 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 631 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 632 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 633 .arg(audiotime) 634 .arg(audbuf_timecode) 635 .arg(totalbuffer) 636 .arg(soundcard_buffer) 637 .arg(effdspstretched) 638 .arg(audio_bytes_per_sample) 639 .arg(audio_stretchfactor) 640 ); 641 #endif 451 642 452 643 pthread_mutex_unlock(&avsync_lock); 453 644 pthread_mutex_unlock(&audio_buflock); … … 458 649 { 459 650 // NOTE: This function is not threadsafe 460 651 int afree = audiofree(true); 461 int abps = audio_bytes_per_sample;652 int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 462 653 int len = samples * abps; 463 654 464 655 // Check we have enough space to write the data 465 656 if (need_resampler && src_ctx) 466 657 len = (int)ceilf(float(len) * src_data.src_ratio); 467 658 659 // include samples in upmix buffer that may be flushed 660 if (needs_upmix && upmixer) 661 len += upmixer->numUnprocessedSamples()*abps; 662 468 663 if (pSoundStretch) 469 664 len += (pSoundStretch->numUnprocessedSamples() + 470 665 (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps; … … 520 715 // NOTE: This function is not threadsafe 521 716 522 717 int afree = audiofree(true); 523 int abps = audio_bytes_per_sample;718 int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 524 719 int len = samples * abps; 525 720 526 721 // Check we have enough space to write the data 527 722 if (need_resampler && src_ctx) 528 723 len = (int)ceilf(float(len) * src_data.src_ratio); 529 724 725 // include samples in upmix buffer that may be flushed 726 if (needs_upmix && upmixer) 727 len += upmixer->numUnprocessedSamples()*abps; 728 530 729 if (pSoundStretch) 531 730 { 532 731 len += (pSoundStretch->numUnprocessedSamples() + … … 575 774 576 775 int AudioOutputBase::WaitForFreeSpace(int samples) 577 776 { 578 int len = samples * audio_bytes_per_sample; 777 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 778 int len = samples * abps; 579 779 int afree = audiofree(false); 580 780 581 781 while (len > afree) 582 782 { 583 783 if (blocking) 584 784 { 585 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +785 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 586 786 QString("(need %1, available %2)").arg(len).arg(afree)); 587 787 588 788 // wait for more space … … 591 791 } 592 792 else 593 793 { 594 VERBOSE(VB_IMPORTANT, LOC_ERR + 595 "Audio buffer overflow, audio data lost!"); 596 samples = afree / audio_bytes_per_sample; 597 len = samples * audio_bytes_per_sample; 794 VERBOSE(VB_IMPORTANT, LOC_ERR + 795 QString("Audio buffer overflow, %1 audio samples lost!") 796 .arg(samples - (afree / abps))); 797 samples = afree / abps; 798 len = samples * abps; 598 799 if (src_ctx) 599 800 { 600 801 int error = src_reset(src_ctx); … … 619 820 620 821 int afree = audiofree(false); 621 822 622 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 623 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 624 .arg(samples * audio_bytes_per_sample) 625 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 823 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 824 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 825 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6") 826 .arg(samples) 827 .arg(samples * abps) 828 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 829 .arg(needs_upmix) 830 ); 626 831 627 len = WaitForFreeSpace(samples); 628 629 if (interleaved) 832 if (upmixer && needs_upmix) 630 833 { 631 char *mybuf = (char*)buffer; 632 int bdiff = AUDBUFSIZE - org_waud; 633 if (bdiff < len) 834 int out_samples = 0; 835 int step = (interleaved)?source_audio_channels:1; 836 len = WaitForFreeSpace(samples); // test 837 for(int itemp=0; itemp<samples; ) 634 838 { 635 memcpy(audiobuffer + org_waud, mybuf, bdiff); 636 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 839 // just in case it does a processing cycle, release the lock 840 // to allow the output loop to do output 841 pthread_mutex_unlock(&audio_buflock); 842 if (audio_bytes == 2) 843 itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 844 else 845 itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 846 pthread_mutex_lock(&audio_buflock); 847 848 int copy_samples = upmixer->numSamples(); 849 if (copy_samples) 850 { 851 int copy_len = copy_samples * abps; 852 out_samples += copy_samples; 853 if (out_samples > samples) 854 len = WaitForFreeSpace(out_samples); 855 int bdiff = AUDBUFSIZE - org_waud; 856 if (bdiff < copy_len) 857 { 858 int bdiff_samples = bdiff/abps; 859 upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples); 860 upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples)); 861 } 862 else 863 { 864 upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples); 865 } 866 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 867 } 637 868 } 638 else 639 memcpy(audiobuffer + org_waud, mybuf, len); 640 641 org_waud = (org_waud + len) % AUDBUFSIZE; 642 } 643 else 869 if (samples > 0) 870 { 871 len = WaitForFreeSpace(out_samples); 872 } 873 samples = out_samples; 874 } 875 else 644 876 { 645 char **mybuf = (char**)buffer; 646 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 877 len = WaitForFreeSpace(samples); 878 879 if (interleaved) 647 880 { 648 for (int chan = 0; chan < audio_channels; chan++) 881 char *mybuf = (char*)buffer; 882 int bdiff = AUDBUFSIZE - org_waud; 883 if (bdiff < len) 649 884 { 650 audiobuffer[org_waud++] = mybuf[chan][itemp]; 651 if (audio_bits == 16) 652 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 885 memcpy(audiobuffer + org_waud, mybuf, bdiff); 886 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 887 } 888 else 889 memcpy(audiobuffer + org_waud, mybuf, len); 890 891 org_waud = (org_waud + len) % AUDBUFSIZE; 892 } 893 else 894 { 895 char **mybuf = (char**)buffer; 896 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 897 { 898 for (int chan = 0; chan < audio_channels; chan++) 899 { 900 audiobuffer[org_waud++] = mybuf[chan][itemp]; 901 if (audio_bits == 16) 902 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 653 903 654 if (org_waud >= AUDBUFSIZE) 655 org_waud -= AUDBUFSIZE; 904 if (org_waud >= AUDBUFSIZE) 905 org_waud -= AUDBUFSIZE; 906 } 656 907 } 657 908 } 658 909 } 659 910 660 if ( pSoundStretch)911 if (samples > 0) 661 912 { 662 // does not change the timecode, only the number of samples 663 // back to orig pos 664 org_waud = waud; 665 int bdiff = AUDBUFSIZE - org_waud; 666 int nSamplesToEnd = bdiff/audio_bytes_per_sample; 667 if (bdiff < len) 913 if (pSoundStretch) 668 914 { 669 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +670 org_waud), nSamplesToEnd);671 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,672 (len - bdiff) / audio_bytes_per_sample);673 }674 else675 {676 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +677 org_waud), len / audio_bytes_per_sample);678 }679 915 680 int newLen = 0; 681 int nSamples; 682 len = WaitForFreeSpace(pSoundStretch->numSamples() * 683 audio_bytes_per_sample); 684 do 685 { 686 int samplesToGet = len/audio_bytes_per_sample; 687 if (samplesToGet > nSamplesToEnd) 916 // does not change the timecode, only the number of samples 917 // back to orig pos 918 org_waud = waud; 919 int bdiff = AUDBUFSIZE - org_waud; 920 int nSamplesToEnd = bdiff/abps; 921 if (bdiff < len) 688 922 { 689 samplesToGet = nSamplesToEnd; 923 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 924 org_waud), nSamplesToEnd); 925 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 926 (len - bdiff) / abps); 690 927 } 928 else 929 { 930 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 931 org_waud), len / abps); 932 } 691 933 692 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 693 (audiobuffer + org_waud), samplesToGet); 694 if (nSamples == nSamplesToEnd) 934 if (encoder) 695 935 { 696 org_waud = 0; 697 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 936 // pull out a packet's worth and reencode it until we dont have enough 937 // for any more packets 938 soundtouch::SAMPLETYPE* temp_buff = 939 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 940 size_t frameSize = encoder->FrameSize()/abps; 941 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 942 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 943 .arg(frameSize) 944 .arg(encoder->FrameSize()) 945 .arg(pSoundStretch->numSamples()) 946 ); 947 // process the same number of samples as it creates a full encoded buffer 948 // just like before 949 while (pSoundStretch->numSamples() >= frameSize) 950 { 951 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 952 int amount = encoder->Encode(temp_buff); 953 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 954 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 955 .arg(amount) 956 .arg(got) 957 .arg(pSoundStretch->numSamples()) 958 ); 959 if (amount == 0) 960 continue; 961 //len = WaitForFreeSpace(amount); 962 char * ob = encoder->GetOutBuff(); 963 if (amount >= bdiff) 964 { 965 memcpy(audiobuffer + org_waud, ob, bdiff); 966 ob += bdiff; 967 amount -= bdiff; 968 org_waud = 0; 969 } 970 if (amount > 0) 971 memcpy(audiobuffer + org_waud, ob, amount); 972 bdiff = AUDBUFSIZE - amount; 973 org_waud += amount; 974 } 698 975 } 699 976 else 700 977 { 701 org_waud += nSamples * audio_bytes_per_sample; 702 nSamplesToEnd -= nSamples; 978 int newLen = 0; 979 int nSamples; 980 len = WaitForFreeSpace(pSoundStretch->numSamples() * 981 audio_bytes_per_sample); 982 do 983 { 984 int samplesToGet = len/audio_bytes_per_sample; 985 if (samplesToGet > nSamplesToEnd) 986 { 987 samplesToGet = nSamplesToEnd; 988 } 989 990 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 991 (audiobuffer + org_waud), samplesToGet); 992 if (nSamples == nSamplesToEnd) 993 { 994 org_waud = 0; 995 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 996 } 997 else 998 { 999 org_waud += nSamples * audio_bytes_per_sample; 1000 nSamplesToEnd -= nSamples; 1001 } 1002 1003 newLen += nSamples * audio_bytes_per_sample; 1004 len -= nSamples * audio_bytes_per_sample; 1005 } while (nSamples > 0); 703 1006 } 1007 } 704 1008 705 newLen += nSamples * audio_bytes_per_sample; 706 len -= nSamples * audio_bytes_per_sample; 707 } while (nSamples > 0); 708 } 1009 waud = org_waud; 1010 lastaudiolen = audiolen(false); 709 1011 710 waud = org_waud; 711 lastaudiolen = audiolen(false); 1012 if (timecode < 0) 1013 { 1014 // mythmusic doesn't give timestamps.. 1015 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1016 } 1017 1018 samples_buffered += samples; 1019 1020 /* we want the time at the end -- but the file format stores 1021 time at the start of the chunk. */ 1022 // even with timestretch, timecode is still calculated from original 1023 // sample count 1024 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 712 1025 713 samples_buffered += samples; 714 715 if (timecode < 0) 716 { 717 // mythmusic doesn't give timestamps.. 718 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1026 if (interleaved) 1027 dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits); 719 1028 } 720 721 /* we want the time at the end -- but the file format stores722 time at the start of the chunk. */723 // even with timestretch, timecode is still calculated from original724 // sample count725 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);726 1029 727 if (interleaved)728 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);729 730 1030 pthread_mutex_unlock(&audio_buflock); 731 1031 } 732 1032 … … 739 1039 740 1040 if (source_bitrate == -1) 741 1041 { 742 source_bitrate = audio_samplerate * audio_channels * audio_bits;1042 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 743 1043 } 744 1044 745 1045 if (ct / 1000 != current_seconds) … … 747 1047 current_seconds = ct / 1000; 748 1048 OutputEvent e(current_seconds, ct, 749 1049 source_bitrate, audio_samplerate, audio_bits, 750 audio_channels);1050 source_audio_channels); 751 1051 dispatch(e); 752 1052 } 753 1053 } … … 780 1080 space_on_soundcard = getSpaceOnSoundcard(); 781 1081 782 1082 if (space_on_soundcard != last_space_on_soundcard) { 783 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1083 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 784 1084 .arg(space_on_soundcard)); 785 1085 last_space_on_soundcard = space_on_soundcard; 786 1086 } … … 793 1093 WriteAudio(zeros, fragment_size); 794 1094 } else { 795 1095 // this should never happen now -dag 796 VERBOSE(VB_AUDIO , LOC +1096 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 797 1097 QString("waiting for space on soundcard " 798 1098 "to write zeros: have %1 need %2") 799 1099 .arg(space_on_soundcard).arg(fragment_size)); … … 829 1129 if (fragment_size > audiolen(true)) 830 1130 { 831 1131 if (audiolen(true) > 0) // only log if we're sending some audio 832 VERBOSE(VB_AUDIO , LOC +1132 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 833 1133 QString("audio waiting for buffer to fill: " 834 1134 "have %1 want %2") 835 1135 .arg(audiolen(true)).arg(fragment_size)); 836 1136 837 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1137 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 838 1138 pthread_mutex_lock(&audio_buflock); 839 1139 pthread_cond_broadcast(&audio_bufsig); 840 1140 pthread_mutex_unlock(&audio_buflock); … … 848 1148 if (fragment_size > space_on_soundcard) 849 1149 { 850 1150 if (space_on_soundcard != last_space_on_soundcard) { 851 VERBOSE(VB_AUDIO , LOC +1151 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 852 1152 QString("audio waiting for space on soundcard: " 853 1153 "have %1 need %2") 854 1154 .arg(space_on_soundcard).arg(fragment_size)); … … 910 1210 911 1211 /* update raud */ 912 1212 raud = (raud + fragment_size) % AUDBUFSIZE; 913 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1213 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 914 1214 pthread_cond_broadcast(&audio_bufsig); 915 1215 916 1216 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); … … 3673 3676 3674 3677 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3675 3678 { 3679 // can only disable never reenable as once timestretch is on its on for the session 3680 if (disable_passthru) 3681 return; 3676 3682 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3677 3683 { 3678 3684 disable_passthru = disable; … … 3705 3711 AVCodecContext *codec_ctx = NULL; 3706 3712 AudioInfo old_in = audioIn; 3707 3713 AudioInfo old_out = audioOut; 3714 bool using_passthru = false; 3708 3715 3709 3716 if ((currentTrack[kTrackTypeAudio] >= 0) && 3710 3717 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3716 3723 assert(curstream->codec); 3717 3724 codec_ctx = curstream->codec; 3718 3725 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3719 !disable_passthru &&3720 3726 (codec_ctx->codec_id == CODEC_ID_AC3)); 3721 3727 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3722 !disable_passthru &&3723 3728 (codec_ctx->codec_id == CODEC_ID_DTS)); 3729 using_passthru = do_ac3_passthru || do_dts_passthru; 3724 3730 info = AudioInfo(codec_ctx->codec_id, 3725 3731 codec_ctx->sample_rate, codec_ctx->channels, 3726 do_ac3_passthru || do_dts_passthru);3732 using_passthru && !disable_passthru); 3727 3733 } 3728 3734 3729 3735 if (info == audioIn) 3730 3736 return false; // no change 3731 3737 3738 QString ptmsg = ""; 3739 if (using_passthru) 3740 { 3741 ptmsg = QString(" using passthru"); 3742 } 3732 3743 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3733 3744 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3734 3745 3735 3746 audioOut = audioIn = info; 3736 if ( audioIn.do_passthru)3747 if (using_passthru) 3737 3748 { 3738 3749 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3739 audioOut.channels = 2; 3740 audioOut.sample_rate = 48000; 3741 audioOut.sample_size = 4; 3750 AudioInfo digInfo = audioOut; 3751 if (!disable_passthru) 3752 { 3753 digInfo.channels = 2; 3754 digInfo.sample_rate = 48000; 3755 digInfo.sample_size = 4; 3756 } 3757 if (audioOut.channels > max_channels) 3758 { 3759 audioOut.channels = max_channels; 3760 audioOut.sample_size = audioOut.channels * 2; 3761 codec_ctx->channels = audioOut.channels; 3762 } 3763 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3764 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3765 .arg(digInfo.toString()) 3766 .arg(old_in.toString()).arg(old_out.toString()) 3767 .arg(audioIn.toString()).arg(audioOut.toString())); 3768 3769 if (digInfo.sample_rate > 0) 3770 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3771 3772 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3773 digInfo.sample_rate, audioIn.do_passthru); 3774 // allow the audio stuff to reencode 3775 GetNVP()->SetAudioCodec(codec_ctx); 3776 GetNVP()->ReinitAudio(); 3777 return true; 3742 3778 } 3743 3779 else 3744 3780 { 3745 if (audioOut.channels > MAX_OUTPUT_CHANNELS)3781 if (audioOut.channels > max_channels) 3746 3782 { 3747 audioOut.channels = MAX_OUTPUT_CHANNELS;3783 audioOut.channels = max_channels; 3748 3784 audioOut.sample_size = audioOut.channels * 2; 3749 codec_ctx->channels = MAX_OUTPUT_CHANNELS;3785 codec_ctx->channels = audioOut.channels; 3750 3786 } 3751 3787 } 3788 bool audiook; 3752 3789 3753 3790 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 3754 3791 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 3761 3798 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3762 3799 audioOut.sample_rate, 3763 3800 audioIn.do_passthru); 3764 GetNVP()->ReinitAudio(); 3801 // allow the audio stuff to reencode 3802 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3803 QString errMsg = GetNVP()->ReinitAudio(); 3804 audiook = errMsg.isEmpty(); 3765 3805 3766 3806 return true; 3767 3807 } -
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;
