Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Handle multiple combinations of channels configurations.

- Refactor libsountouch to handle 6.1 -> 7.1 upmixing. Rewrite code to remove duplicates.
- Downmixer: treat 7 channels audio as 6.1 (3F3R.1). The new downmixer is slower but the code is far more readable and can handle any configuration changes through simply adding the proper downmix matrix
- Handle any speaker configurations and upmix/downmix to whatever is supported by the hardware
- Expand audio speaker test, it can now simulate 5.0 and 6.1 input. Set TestingChannels via a command line override.

Star Wars lovers rejoice, myth couldn't play 6.1 audio before, it will now be upmixed to 7.1 or downmixed to 5.1 appropriately.
We also properly handle DTS-ES Discrete. I believe Myth is the only media player properly handling that type of media without loosing channel information

These new capabilities mean that we can't encounter audio we wouldn't be able to play.
  • Loading branch information...
commit 819649ffd2811fb1012beb62985225bf747c59e4 1 parent 0acff82
Jean-Yves Avenard jyavenard authored
110 mythtv/libs/libmyth/audio/audiooutputbase.cpp
View
@@ -33,8 +33,8 @@
#define QUALITY_MEDIUM 1
#define QUALITY_HIGH 2
-// 1,2 and 5 channels are currently valid for upmixing if required
-#define UPMIX_CHANNEL_MASK ((1<<1)|(1<<2)|(1<<5))
+// 1,2,5 and 7 channels are currently valid for upmixing if required
+#define UPMIX_CHANNEL_MASK ((1<<1)|(1<<2)|(1<<5)|1<<7)
#define IS_VALID_UPMIX_CHANNEL(ch) ((1 << (ch)) & UPMIX_CHANNEL_MASK)
static const char *quality_string(int q)
@@ -456,53 +456,63 @@ void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
bool lneeds_upmix = false;
bool lneeds_downmix = false;
bool lreenc = false;
+ bool lenc = false;
if (!settings.use_passthru)
{
- // update channels configuration if source_channels has changed
- if (lsource_channels > configured_channels)
+ // Do we upmix stereo or mono?
+ lconfigured_channels =
+ (upmix_default && lsource_channels <= 2) ? 6 : lsource_channels;
+ bool cando_channels =
+ output_settings->IsSupportedChannels(lconfigured_channels);
+
+ // check if the number of channels could be transmitted via AC3 encoding
+ lenc = output_settingsdigital->canFeature(FEATURE_AC3) &&
+ (!output_settings->canFeature(FEATURE_LPCM) &&
+ lconfigured_channels > 2 && lconfigured_channels <= 6);
+
+ if (!lenc && !cando_channels)
{
- if (lsource_channels <= 6)
- lconfigured_channels = min(max_channels, 6);
- else if (lsource_channels > 6)
- lconfigured_channels = max_channels;
- }
- else
- {
- if (!output_settings->IsSupportedChannels(lsource_channels))
+ // if hardware doesn't support source audio configuration
+ // we will upmix/downmix to what we can
+ // (can safely assume hardware supports stereo)
+ switch (lconfigured_channels)
{
- // if hardware doesn't support source audio configuration
- // we will upmix/downmix to what we can
- // (can safely assume hardware supports stereo)
- switch (lsource_channels)
- {
- case 1:
- lconfigured_channels = upmix_default ? max_channels : 2;
- break;
- case 2:
- //Will never happen
- case 3:
- case 4:
- case 6:
- lconfigured_channels = 2;
- break;
- case 5:
- case 7:
- if (output_settings->IsSupportedChannels(6))
- lconfigured_channels = 6;
- else
- lconfigured_channels = 2;
- break;
- default:
- lconfigured_channels = max_channels;
+ case 7:
+ lconfigured_channels = 8;
+ break;
+ case 8:
+ case 5:
+ lconfigured_channels = 6;
break;
- }
+ case 6:
+ case 4:
+ case 3:
+ case 2: //Will never happen
+ lconfigured_channels = 2;
+ break;
+ case 1:
+ lconfigured_channels = upmix_default ? 6 : 2;
+ break;
+ default:
+ lconfigured_channels = 2;
+ break;
}
- else
- lconfigured_channels =
- (upmix_default && lsource_channels <= 2) ?
- max_channels : lsource_channels;
}
+ // Make sure we never attempt to output more than what we can
+ // the upmixer can only upmix to 6 channels when source < 6
+ if (lsource_channels <= 6)
+ lconfigured_channels = min(lconfigured_channels, 6);
+ lconfigured_channels = min(lconfigured_channels, max_channels);
+ /* Encode to AC-3 if we're allowed to passthru but aren't currently
+ and we have more than 2 channels but multichannel PCM is not
+ supported or if the device just doesn't support the number of
+ channels */
+ lenc = output_settingsdigital->canFeature(FEATURE_AC3) &&
+ ((!output_settings->canFeature(FEATURE_LPCM) &&
+ lconfigured_channels > 2) ||
+ !output_settings->IsSupportedChannels(lconfigured_channels));
+
/* Might we reencode a bitstream that's been decoded for timestretch?
If the device doesn't support the number of channels - see below */
if (output_settingsdigital->canFeature(FEATURE_AC3) &&
@@ -515,8 +525,6 @@ void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
if (IS_VALID_UPMIX_CHANNEL(settings.channels) &&
settings.channels < lconfigured_channels)
{
- lconfigured_channels =
- (lconfigured_channels > 6) ? 6 : lconfigured_channels;
VBAUDIO(QString("Needs upmix from %1 -> %2 channels")
.arg(settings.channels).arg(lconfigured_channels));
settings.channels = lconfigured_channels;
@@ -581,6 +589,7 @@ void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
needs_downmix = lneeds_downmix;
format = output_format = settings.format;
source_samplerate = samplerate = settings.samplerate;
+ enc = lenc;
killaudio = pauseaudio = false;
was_paused = true;
@@ -601,15 +610,6 @@ void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
.arg(samplerate/1000)
.arg(source_channels));
- /* Encode to AC-3 if we're allowed to passthru but aren't currently
- and we have more than 2 channels but multichannel PCM is not supported
- or if the device just doesn't support the number of channels */
- enc = (!passthru &&
- output_settingsdigital->canFeature(FEATURE_AC3) &&
- ((!output_settings->canFeature(FEATURE_LPCM) &&
- configured_channels > 2) ||
- !output_settings->IsSupportedChannels(channels)));
-
VBAUDIO(QString("enc(%1), passthru(%2), features (%3) "
"configured_channels(%4), %5 channels supported(%6) "
"max_channels(%7)")
@@ -685,10 +685,11 @@ void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
VBAUDIO("Reencoding decoded AC-3/DTS to AC-3");
VBAUDIO(QString("Creating AC-3 Encoder with sr = %1, ch = %2")
- .arg(samplerate).arg(channels));
+ .arg(samplerate).arg(configured_channels));
encoder = new AudioOutputDigitalEncoder();
- if (!encoder->Init(CODEC_ID_AC3, 448000, samplerate, channels))
+ if (!encoder->Init(CODEC_ID_AC3, 448000, samplerate,
+ configured_channels))
{
Error("AC-3 encoder initialization failed");
delete encoder;
@@ -772,7 +773,6 @@ void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
VolumeBase::SyncVolume();
VolumeBase::UpdateVolume();
- // Upmix Mono, Stereo or 5.0 to 5.1
if (needs_upmix && IS_VALID_UPMIX_CHANNEL(source_channels) &&
configured_channels > 2)
{
98 mythtv/libs/libmyth/audio/audiooutputdownmix.cpp
View
@@ -1,3 +1,21 @@
+/*
+Copyright (C) 2010-2011 Jean-Yves Avenard
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
#include "audiooutputbase.h"
#include "audiooutputdownmix.h"
@@ -23,10 +41,11 @@
2F2-LFE L R LFE LS RS
3F2 L R C LS RS
3F2-LFE L R C LFE LS RS
- 3F4 L R C Rls Rrs LS RS
+ 3F3R-LFE L R C LFE BC LS RS
3F4-LFE L R C LFE Rls Rrs LS RS
*/
+static const float m6db = 0.5;
static const float m3db = 0.7071067811865476f; // 3dB = SQRT(2)
static const float mm3db = -0.7071067811865476f; // -3dB = SQRT(1/2)
static const float msqrt_1_3 = -0.577350269189626f; // -SQRT(1/3)
@@ -83,15 +102,15 @@ static const float stereo_matrix[8][8][2] =
{ msqrt_1_3, sqrt_2_3 }, // RS
},
-// 3F4R L R
+// 3F3R.1 L R
{
{ 1, 0 }, // L
{ 0, 1 }, // R
{ m3db, m3db }, // C
- { sqrt_2_3by3db, msqrt_1_3bym3db }, // Rls
- { msqrt_1_3bym3db, sqrt_2_3by3db }, // Rrs
- { sqrt_2_3by3db, msqrt_1_3bym3db }, // LS
- { msqrt_1_3bym3db, sqrt_2_3by3db }, // RS
+ { 0, 0 }, // LFE
+ { m6db, m6db }, // Cs
+ { sqrt_2_3, msqrt_1_3 }, // LS
+ { msqrt_1_3, sqrt_2_3 }, // RS
},
// 3F4R.1 L R
@@ -107,26 +126,37 @@ static const float stereo_matrix[8][8][2] =
}
};
-static const float s51_matrix[2][8][6] =
-{
- // 3F4R in -> 3F2R.1 out
- // L R C LFE LS RS
+static const float s51_matrix[3][8][6] =
+{
+ // 3F2R.1 in -> 3F2R.1 out
+ // L R C LFE LS RS
{
{ 1, 0, 0, 0, 0, 0 }, // L
{ 0, 1, 0, 0, 0, 0 }, // R
{ 0, 0, 1, 0, 0, 0 }, // C
- { 0, 0, 0, 0, m3db, 0 }, // Rls
- { 0, 0, 0, 0, 0, m3db }, // Rrs
- { 0, 0, 0, 0, m3db, 0 }, // LS
- { 0, 0, 0, 0, 0, m3db }, // RS
+ { 0, 0, 0, 1, 0, 0 }, // LFE
+ { 0, 0, 0, 0, 1, 0 }, // LS
+ { 0, 0, 0, 0, 0, 1 }, // RS
+ },
+ // 3F3R.1 in -> 3F2R.1 out
+ // Used coefficient found at http://www.yamahaproaudio.com/training/self_training/data/smqr_en.pdf
+ // L R C LFE LS RS
+ {
+ { 1, 0, 0, 0, 0, 0 }, // L
+ { 0, 1, 0, 0, 0, 0 }, // R
+ { 0, 0, 1, 0, 0, 0 }, // C
+ { 0, 0, 0, 1, 0, 0 }, // LFE
+ { 0, 0, 0, 0, m3db, m3db }, // Cs
+ { 0, 0, 0, 0, 1, 0 }, // LS
+ { 0, 0, 0, 0, 0, 1 }, // RS
},
// 3F4R.1 -> 3F2R.1 out
- // L R C LFE LS RS
+ // L R C LFE LS RS
{
{ 1, 0, 0, 0, 0, 0 }, // L
{ 0, 1, 0, 0, 0, 0 }, // R
{ 0, 0, 1, 0, 0, 0 }, // C
- { 0, 0, 0, 1, 0, 1 }, // LFE
+ { 0, 0, 0, 1, 0, 0 }, // LFE
{ 0, 0, 0, 0, m3db, 0 }, // Rls
{ 0, 0, 0, 0, 0, m3db }, // Rrs
{ 0, 0, 0, 0, m3db, 0 }, // LS
@@ -160,36 +190,18 @@ int AudioOutputDownmix::DownmixFrames(int channels_in, int channels_out,
}
else if (channels_out == 6)
{
- // dummy 5.1 -> 5.1 downmixer for test purposes
- if (channels_in == 6)
- {
- int lensamples = channels_in;
- int lenbytes = lensamples * sizeof(float);
- for (int n=0; n < frames; n++)
- {
- memcpy(dst, src, lenbytes);
- src += lensamples;
- dst += lensamples;
- }
- }
- else
+ float tmp;
+ int index = channels_in - 6;
+ for (int n=0; n < frames; n++)
{
- int lensamples = channels_in - 4;
- int lenbytes = lensamples * sizeof(float);
- for (int n=0; n < frames; n++)
+ for (int i=0; i < channels_out; i++)
{
- memcpy(dst, src, lenbytes);
- src += lensamples;
- dst += 4;
- //read value first, as src and dst can overlap
- float ls = src[0];
- float rs = src[1];
- float rls = src[2];
- float rrs = src[3];
- *dst++ = ls * m3db + rls * m3db; // LS = LS*-3dB + Rls*-3dB
- *dst++ = rs * m3db + rrs * m3db; // RS = RS*-3dB + Rrs*-3dB
- src += 4;
+ tmp = 0.0f;
+ for (int j=0; j < channels_in; j++)
+ tmp += src[j] * s51_matrix[index][j][i];
+ *dst++ = tmp;
}
+ src += channels_in;
}
}
else
311 mythtv/libs/libmythfreesurround/freesurround.cpp
View
@@ -1,5 +1,6 @@
/*
Copyright (C) 2007 Christian Kothe, Mark Spieth
+Copyright (C) 2010-2011 Jean-Yves Avenard
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -40,6 +41,7 @@ using namespace std;
static const unsigned default_block_size = SURROUND_BUFSIZE;
// Gain of center and lfe channels in passive mode (sqrt 0.5)
static const float center_level = 0.707107;
+static const float m3db = 0.7071067811865476f; // 3dB = SQRT(2)
unsigned int block_size = default_block_size;
@@ -101,18 +103,21 @@ class object_pool
struct buffers
{
buffers(unsigned int s):
- l(s),r(s),c(s),ls(s),rs(s),lfe(s) { }
+ l(s),r(s),c(s),ls(s),rs(s),lfe(s), rls(s), rrs(s) { }
void resize(unsigned int s)
{
l.resize(s); r.resize(s); lfe.resize(s);
ls.resize(s); rs.resize(s); c.resize(s);
+ rls.resize(s); rrs.resize(s);
}
void clear()
{
l.clear(); r.clear(); lfe.clear();
ls.clear(); rs.clear(); c.clear();
+ rls.clear(); rrs.clear();
}
- std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs; // for demultiplexing
+ std::vector<float> l,r,c,ls,rs,lfe,cs,lcs,rcs,
+ rls, rrs; // for demultiplexing
};
// construction methods
@@ -224,16 +229,39 @@ uint FreeSurround::putFrames(void* buffer, uint numFrames, uint numChannels)
bool process = true;
float *samples = (float *)buffer;
// demultiplex
- switch (surround_mode)
+
+ float **inputs = decoder->getInputBuffers();
+ float *lt = &inputs[0][ic];
+ float *rt = &inputs[1][ic];
+
+ if ((surround_mode != SurroundModePassive) && (ic+numFrames > bs))
+ {
+ numFrames = bs - ic;
+ }
+
+ switch (numChannels)
{
- case SurroundModePassive:
- switch (numChannels)
+ case 1:
+ switch (surround_mode)
{
- case 1:
+ case SurroundModePassive:
for (i = 0; i < numFrames && ic < bs; i++,ic++)
bufs->l[ic] = bufs->c[ic] = bufs->r[ic] = samples[i];
+ process = false;
+ break;
+ default:
+ for (i=0; i<numFrames; i++)
+ *lt++ = *rt++ = *samples++;
+ process = true;
break;
- case 2:
+ }
+ channels = 6;
+ break;
+
+ case 2:
+ switch (surround_mode)
+ {
+ case SurroundModePassive:
for (i = 0; i < numFrames && ic < bs; i++,ic++)
{
float lt = *samples++;
@@ -243,98 +271,92 @@ uint FreeSurround::putFrames(void* buffer, uint numFrames, uint numChannels)
bufs->r[ic] = rt;
bufs->ls[ic] = bufs->rs[ic] = (lt-rt) * center_level;
}
+ process = false;
break;
- case 5:
- for (i = 0; i < numFrames && ic < bs; i++,ic++)
- {
- float lt = *samples++;
- float rt = *samples++;
- float c = *samples++;
- float lfe = (lt+rt) * center_level;
- float ls = *samples++;
- float rs = *samples++;
- bufs->l[ic] = lt;
- bufs->lfe[ic] = lfe;
- bufs->c[ic] = c;
- bufs->r[ic] = rt;
- bufs->ls[ic] = ls;
- bufs->rs[ic] = rs;
- }
- break;
- }
- in_count = 0;
- out_count = processed_size = ic;
- processed = false;
- latency_frames = 0;
- break;
-
- default:
- float **inputs = decoder->getInputBuffers();
- float *lt = &inputs[0][ic];
- float *rt = &inputs[1][ic];
- if ((ic+numFrames) > bs)
- numFrames = bs - ic;
- switch (numChannels)
- {
- case 1:
- for (i=0; i<numFrames; i++)
- *lt++ = *rt++ = *samples++;
- break;
- case 2:
+ default:
for (i=0; i<numFrames; i++)
{
*lt++ = *samples++;
*rt++ = *samples++;
}
- break;
- case 5:
- // 5 ch is always passive mode,
- for (i = 0; i < numFrames && ic < bs; i++,ic++)
- {
- float l = *samples++;
- float r = *samples++;
- float c = *samples++;
- float lfe = (l+r) * center_level;
- float ls = *samples++;
- float rs = *samples++;
- bufs->l[ic] = l;
- bufs->lfe[ic] = lfe;
- bufs->c[ic] = c;
- bufs->r[ic] = r;
- bufs->ls[ic] = ls;
- bufs->rs[ic] = rs;
- }
- process = false;
+ process = true;
break;
}
- if (process)
+ channels = 6;
+ break;
+
+ case 5:
+ for (i = 0; i < numFrames && ic < bs; i++,ic++)
{
- ic += numFrames;
- if (ic != bs)
- {
- // dont modify unless no processing is to be done
- // for audiotime consistency
- in_count = ic;
- break;
- }
- processed = process;
- // process_block takes some time so dont update in and out count
- // before its finished so that Audiotime is correctly calculated
- process_block();
- in_count = 0;
- out_count = bs;
- processed_size = bs;
- latency_frames = block_size/2;
+ float lt = *samples++;
+ float rt = *samples++;
+ float c = *samples++;
+ float ls = *samples++;
+ float rs = *samples++;
+ bufs->l[ic] = lt;
+ bufs->lfe[ic] = 0.0f;
+ bufs->c[ic] = c;
+ bufs->r[ic] = rt;
+ bufs->ls[ic] = ls;
+ bufs->rs[ic] = rs;
}
- else
+ process = false;
+ channels = 6;
+ break;
+
+ case 7:
+ for (i = 0; i < numFrames && ic < bs; i++,ic++)
{
- in_count = 0;
- out_count = processed_size = ic;
- processed = false;
- latency_frames = 0;
+ // 3F3R-LFE L R C LFE BC LS RS
+ float lt = *samples++;
+ float rt = *samples++;
+ float c = *samples++;
+ float lfe = *samples++;
+ float cs = *samples++;
+ float ls = *samples++;
+ float rs = *samples++;
+ bufs->l[ic] = lt;
+ bufs->lfe[ic] = lfe;
+ bufs->c[ic] = c;
+ bufs->r[ic] = rt;
+ bufs->ls[ic] = ls;
+ bufs->rs[ic] = rs;
+ bufs->rls[ic] = bufs->rrs[ic] = cs * m3db;
}
+ process = false;
+ channels = 8;
+ break;
+ default:
break;
}
+ if (process)
+ {
+ ic += numFrames;
+ if (ic != bs)
+ {
+ // dont modify unless no processing is to be done
+ // for audiotime consistency
+ in_count = ic;
+ }
+ else
+ {
+ processed = process;
+ // process_block takes some time so dont update in and out count
+ // before its finished so that Audiotime is correctly calculated
+ process_block();
+ in_count = 0;
+ out_count = bs;
+ processed_size = bs;
+ latency_frames = block_size/2;
+ }
+ }
+ else
+ {
+ in_count = 0;
+ out_count = processed_size = ic;
+ processed = false;
+ latency_frames = 0;
+ }
LOG(VB_AUDIO | VB_TIMESTAMP, LOG_DEBUG,
QString("FreeSurround::putFrames %1 #ch %2 used %3 generated %4")
@@ -350,66 +372,77 @@ uint FreeSurround::receiveFrames(void *buffer, uint maxFrames)
if (maxFrames > oc) maxFrames = oc;
uint outindex = processed_size - oc;
float *output = (float *)buffer;
-
- switch (surround_mode)
+ if (channels == 8)
+ {
+ float *l = &bufs->l[outindex];
+ float *c = &bufs->c[outindex];
+ float *r = &bufs->r[outindex];
+ float *ls = &bufs->ls[outindex];
+ float *rs = &bufs->rs[outindex];
+ float *lfe = &bufs->lfe[outindex];
+ float *rls = &bufs->rls[outindex];
+ float *rrs = &bufs->rrs[outindex];
+ for (i = 0; i < maxFrames; i++)
+ {
+// printf("1:%f 2:%f 3:%f 4:%f 5:%f 6:%f 7:%f 8:%f\n",
+// *l, *r, *c, *lfe, *rls, *rrs, *ls, *rs);
+
+ // 3F4-LFE L R C LFE Rls Rrs LS RS
+ *output++ = *l++;
+ *output++ = *r++;
+ *output++ = *c++;
+ *output++ = *lfe++;
+ *output++ = *rls++;
+ *output++ = *rrs++;
+ *output++ = *ls++;
+ *output++ = *rs++;
+ }
+ oc -= maxFrames;
+ outindex += maxFrames;
+ }
+ else // channels == 6
{
- case SurroundModePassive:
+ if (processed)
+ {
+ float** outputs = decoder->getOutputBuffers();
+ float *l = &outputs[0][outindex];
+ float *c = &outputs[1][outindex];
+ float *r = &outputs[2][outindex];
+ float *ls = &outputs[3][outindex];
+ float *rs = &outputs[4][outindex];
+ float *lfe = &outputs[5][outindex];
for (i = 0; i < maxFrames; i++)
{
- *output++ = bufs->l[outindex];
- *output++ = bufs->r[outindex];
- *output++ = bufs->c[outindex];
- *output++ = bufs->lfe[outindex];
- *output++ = bufs->ls[outindex];
- *output++ = bufs->rs[outindex];
- oc--;
- outindex++;
- }
- break;
-
- default:
- if (processed)
- {
- float** outputs = decoder->getOutputBuffers();
- float *l = &outputs[0][outindex];
- float *c = &outputs[1][outindex];
- float *r = &outputs[2][outindex];
- float *ls = &outputs[3][outindex];
- float *rs = &outputs[4][outindex];
- float *lfe = &outputs[5][outindex];
- for (i = 0; i < maxFrames; i++)
- {
- *output++ = *l++;
- *output++ = *r++;
- *output++ = *c++;
- *output++ = *lfe++;
- *output++ = *ls++;
- *output++ = *rs++;
- }
- oc -= maxFrames;
- outindex += maxFrames;
+ *output++ = *l++;
+ *output++ = *r++;
+ *output++ = *c++;
+ *output++ = *lfe++;
+ *output++ = *ls++;
+ *output++ = *rs++;
}
- else
+ oc -= maxFrames;
+ outindex += maxFrames;
+ }
+ else
+ {
+ float *l = &bufs->l[outindex];
+ float *c = &bufs->c[outindex];
+ float *r = &bufs->r[outindex];
+ float *ls = &bufs->ls[outindex];
+ float *rs = &bufs->rs[outindex];
+ float *lfe = &bufs->lfe[outindex];
+ for (i = 0; i < maxFrames; i++)
{
- float *l = &bufs->l[outindex];
- float *c = &bufs->c[outindex];
- float *r = &bufs->r[outindex];
- float *ls = &bufs->ls[outindex];
- float *rs = &bufs->rs[outindex];
- float *lfe = &bufs->lfe[outindex];
- for (i = 0; i < maxFrames; i++)
- {
- *output++ = *l++;
- *output++ = *r++;
- *output++ = *c++;
- *output++ = *lfe++;
- *output++ = *ls++;
- *output++ = *rs++;
- }
- oc -= maxFrames;
- outindex += maxFrames;
+ *output++ = *l++;
+ *output++ = *r++;
+ *output++ = *c++;
+ *output++ = *lfe++;
+ *output++ = *ls++;
+ *output++ = *rs++;
}
- break;
+ oc -= maxFrames;
+ outindex += maxFrames;
+ }
}
out_count = oc;
LOG(VB_AUDIO | VB_TIMESTAMP, LOG_DEBUG,
2  mythtv/libs/libmythfreesurround/freesurround.h
View
@@ -86,7 +86,7 @@ class FreeSurround
int processed_size; // amount processed
SurroundMode surround_mode; // 1 of 3 surround modes supported
int latency_frames; // number of frames of incurred latency
+ int channels;
};
#endif
-
52 mythtv/programs/mythfrontend/audiogeneralsettings.cpp
View
@@ -586,10 +586,10 @@ void AudioTestThread::run()
{ 0, 1, 1 }, //stereo
{ }, //not used
{ }, //not used
- { }, //not used
+ { 0, 2, 1, 4, 3 }, //5.0
{ 0, 2, 1, 5, 4, 3 }, //5.1
- { }, //not used
- { 0, 2, 1, 7, 5, 4, 6, 3 }, //7.1
+ { 0, 2, 1, 6, 4, 5, 3 }, //6.1
+ { 0, 2, 1, 7, 5, 4, 6, 3 }, //7.1
};
if (m_audioOutput)
@@ -633,17 +633,24 @@ void AudioTestThread::run()
case 4:
if (m_channels == 6)
channel = "surroundleft";
+ else if (m_channels == 7)
+ channel = "rearright";
else
channel = "rearleft";
break;
case 5:
if (m_channels == 6)
channel = "surroundright";
+ else if (m_channels == 7)
+ channel = "surroundleft";
else
channel = "rearright";
break;
case 6:
- channel = "surroundleft";
+ if (m_channels == 7)
+ channel = "surroundright";
+ else
+ channel = "surroundleft";
break;
case 7:
channel = "surroundright";
@@ -668,8 +675,7 @@ void AudioTestThread::run()
LOG(VB_AUDIO, LOG_ERR, "AddData() Audio buffer "
"overflow, audio data lost!");
}
- // a tad less than 1/48th of a second to avoid underruns
- usleep((1000000 / m_samplerate) * 1000);
+ usleep(m_audioOutput->LengthLastData() * 1000);
}
m_audioOutput->Drain();
m_audioOutput->Pause(true);
@@ -689,17 +695,17 @@ void AudioTestThread::run()
AudioTest::AudioTest(QString main, QString passthrough,
int channels, AudioOutputSettings settings)
: VerticalConfigurationGroup(false, true, false, false),
- m_channels(channels),
m_frontleft(NULL), m_frontright(NULL), m_center(NULL),
m_surroundleft(NULL), m_surroundright(NULL),
m_rearleft(NULL), m_rearright(NULL), m_lfe(NULL),
m_main(main), m_passthrough(passthrough), m_settings(settings),
m_quality(false)
{
+ m_channels = gCoreContext->GetNumSetting("TestingChannels", channels);
setLabel(QObject::tr("Audio Configuration Testing"));
- m_at = new AudioTestThread(this, main, passthrough, channels,
- settings, m_quality);
+ m_at = new AudioTestThread(this, m_main, m_passthrough, m_channels,
+ m_settings, m_quality);
if (!m_at->result().isEmpty())
{
QString msg = main + QObject::tr(" is invalid or not "
@@ -740,17 +746,27 @@ AudioTest::AudioTest(QString main, QString passthrough,
m_rearleft->setLabel(QObject::tr("Rear Left"));
connect(m_rearleft,
SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
+ reargroup->addChild(m_rearleft);
+
+ case 7:
m_rearright = new TransButtonSetting("4");
- m_rearright->setLabel(QObject::tr("Rear Right"));
+ m_rearright->setLabel(QObject::tr(m_channels == 8 ?
+ "Rear Right" : "Rear Center"));
connect(m_rearright,
SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
- reargroup->addChild(m_rearleft);
reargroup->addChild(m_rearright);
-
+
case 6:
- m_surroundleft = new TransButtonSetting(m_channels == 6 ?
- "4" : "6");
+ m_lfe = new TransButtonSetting(m_channels == 6 ? "5" :
+ m_channels == 7 ? "6" : "7");
+ m_lfe->setLabel(QObject::tr("LFE"));
+ connect(m_lfe,
+ SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
+
+ case 5:
+ m_surroundleft = new TransButtonSetting(m_channels == 6 ? "4" :
+ m_channels == 7 ? "5" : "6");
m_surroundleft->setLabel(QObject::tr("Surround Left"));
connect(m_surroundleft,
SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
@@ -758,18 +774,14 @@ AudioTest::AudioTest(QString main, QString passthrough,
m_surroundright->setLabel(QObject::tr("Surround Right"));
connect(m_surroundright,
SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
- m_lfe = new TransButtonSetting(m_channels == 6 ? "5" : "7");
- m_lfe->setLabel(QObject::tr("LFE"));
- connect(m_lfe,
- SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
-
m_center = new TransButtonSetting("1");
m_center->setLabel(QObject::tr("Center"));
connect(m_center,
SIGNAL(pressed(QString)), this, SLOT(toggle(QString)));
frontgroup->addChild(m_center);
middlegroup->addChild(m_surroundleft);
- middlegroup->addChild(m_lfe);
+ if (m_lfe)
+ middlegroup->addChild(m_lfe);
middlegroup->addChild(m_surroundright);
case 2:
Please sign in to comment.
Something went wrong with that request. Please try again.