if (delay < 0)
delay = 0.0;
- delay += stream->m_bufferedTime;
+ delay += stream->m_bufferedTime / stream->m_streamResampleRatio;
return delay;
}
float CEngineStats::GetWaterLevel()
{
+ CSingleLock lock(m_lock);
return (float)m_bufferedSamples / m_sinkSampleRate;
}
m_vizBuffers = NULL;
m_vizBuffersInput = NULL;
m_volume = 1.0;
+ m_volumeScaled = 1.0;
m_aeVolume = 1.0;
m_muted = false;
m_aeMuted = false;
void CActiveAE::Dispose()
{
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
g_Windowing.Unregister(this);
#endif
return;
case CActiveAEControlProtocol::VOLUME:
m_volume = *(float*)msg->data;
+ m_volumeScaled = CAEUtil::GainToScale(CAEUtil::PercentToGain(m_volume));
if (m_sinkHasVolume)
m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::VOLUME, &m_volume, sizeof(float));
return;
case CActiveAEControlProtocol::DEVICECHANGE:
time_t now;
time(&now);
+ CLog::Log(LOGDEBUG,"CActiveAE - device change event");
while (!m_extLastDeviceChange.empty() && (now - m_extLastDeviceChange.front() > 0))
{
m_extLastDeviceChange.pop();
}
m_extLastDeviceChange.push(now);
UnconfigureSink();
+ m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
m_sink.EnumerateSinkList(true);
LoadSettings();
m_extError = false;
m_state = AE_TOP_ERROR;
m_extTimeout = 500;
}
- m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
return;
case CActiveAEControlProtocol::PAUSESTREAM:
CActiveAEStream *stream;
switch (signal)
{
case CActiveAEControlProtocol::DISPLAYRESET:
+ CLog::Log(LOGDEBUG,"CActiveAE - display reset event");
displayReset = true;
case CActiveAEControlProtocol::INIT:
m_extError = false;
if (!displayReset)
{
+ m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE);
m_sink.EnumerateSinkList(true);
LoadSettings();
}
m_stats.SetSuspended(false);
m_extDeferData = false;
return;
+ case CActiveAEControlProtocol::DEVICECHANGE:
+ return;
default:
break;
}
unsigned int buffertime = m_sinkFormat.m_frames / m_sinkFormat.m_sampleRate;
if (buffertime > MAX_BUFFER_TIME)
{
- CLog::Log(LOGWARNING, "ActiveAE::%s - sink returned large buffer of %d ms, reducing to %d ms", __FUNCTION__, buffertime, MAX_BUFFER_TIME*1000);
+ CLog::Log(LOGWARNING, "ActiveAE::%s - sink returned large buffer of %d ms, reducing to %d ms", __FUNCTION__, buffertime, (int)(MAX_BUFFER_TIME*1000));
m_sinkFormat.m_frames = MAX_BUFFER_TIME * m_sinkFormat.m_sampleRate;
}
}
outputFormat = inputFormat;
outputFormat.m_dataFormat = AE_FMT_FLOATP;
outputFormat.m_sampleRate = 48000;
+ outputFormat.m_encodedRate = 48000;
// setup encoder
if (!m_encoder)
// resample buffers for sink
if (m_sinkBuffers &&
- (!CompareFormat(m_sinkBuffers->m_format,m_sinkFormat) || !CompareFormat(m_sinkBuffers->m_inputFormat, sinkInputFormat)))
+ (!CompareFormat(m_sinkBuffers->m_format,m_sinkFormat) ||
+ !CompareFormat(m_sinkBuffers->m_inputFormat, sinkInputFormat) ||
+ m_sinkBuffers->m_format.m_frames != m_sinkFormat.m_frames))
{
m_discardBufferPools.push_back(m_sinkBuffers);
m_sinkBuffers = NULL;
{
format.m_dataFormat = AE_FMT_AC3;
format.m_sampleRate = 48000;
+ format.m_encodedRate = 48000;
format.m_channelLayout = AE_CH_LAYOUT_2_0;
if (mode)
*mode = MODE_TRANSCODE;
CSampleBuffer *buffer;
if (!(*it)->m_drain)
{
- while (time < MAX_CACHE_LEVEL && !(*it)->m_inputBuffers->m_freeSamples.empty())
+ float buftime = (float)(*it)->m_inputBuffers->m_format.m_frames / (*it)->m_inputBuffers->m_format.m_sampleRate;
+ time += buftime * (*it)->m_processingSamples.size();
+ while ((time < MAX_CACHE_LEVEL || (*it)->m_streamIsBuffering) && !(*it)->m_inputBuffers->m_freeSamples.empty())
{
buffer = (*it)->m_inputBuffers->GetFreeBuffer();
(*it)->m_processingSamples.push_back(buffer);
(*it)->m_streamPort->SendInMessage(CActiveAEDataProtocol::STREAMBUFFER, &buffer, sizeof(CSampleBuffer*));
(*it)->IncFreeBuffers();
- time += (float)buffer->pkt->max_nb_samples / buffer->pkt->config.sample_rate;
+ time += buftime;
}
}
else
if ((*it)->m_fadingSamples == -1)
{
(*it)->m_fadingSamples = m_internalFormat.m_sampleRate * (float)(*it)->m_fadingTime / 1000.0f;
- (*it)->m_volume = (*it)->m_fadingBase;
+ if ((*it)->m_fadingSamples > 0)
+ (*it)->m_volume = (*it)->m_fadingBase;
+ else
+ {
+ (*it)->m_volume = (*it)->m_fadingTarget;
+ CSingleLock lock((*it)->m_streamLock);
+ (*it)->m_streamFading = false;
+ }
}
if ((*it)->m_fadingSamples > 0)
{
CSampleBuffer *buffer;
for (it = m_streams.begin(); it != m_streams.end(); ++it)
{
- if (!(*it)->m_resampleBuffers->m_outputSamples.empty())
+ if (!(*it)->m_resampleBuffers->m_outputSamples.empty() && !(*it)->m_paused)
{
buffer = (*it)->m_resampleBuffers->m_outputSamples.front();
(*it)->m_resampleBuffers->m_outputSamples.pop_front();
}
}
}
+ }
- // serve sink buffers
- busy = m_sinkBuffers->ResampleBuffers();
- while(!m_sinkBuffers->m_outputSamples.empty())
- {
- CSampleBuffer *out = NULL;
- out = m_sinkBuffers->m_outputSamples.front();
- m_sinkBuffers->m_outputSamples.pop_front();
- m_sink.m_dataPort.SendOutMessage(CSinkDataProtocol::SAMPLE,
- &out, sizeof(CSampleBuffer*));
- busy = true;
- }
+ // serve sink buffers
+ busy |= m_sinkBuffers->ResampleBuffers();
+ while(!m_sinkBuffers->m_outputSamples.empty())
+ {
+ CSampleBuffer *out = NULL;
+ out = m_sinkBuffers->m_outputSamples.front();
+ m_sinkBuffers->m_outputSamples.pop_front();
+ m_sink.m_dataPort.SendOutMessage(CSinkDataProtocol::SAMPLE,
+ &out, sizeof(CSampleBuffer*));
+ busy = true;
}
return busy;
void CActiveAE::Deamplify(CSoundPacket &dstSample)
{
- if (m_volume < 1.0 || m_muted)
+ if (m_volumeScaled < 1.0 || m_muted)
{
float *buffer;
int nb_floats = dstSample.nb_samples * dstSample.config.channels / dstSample.planes;
- float volume = m_muted ? 0.0f : m_volume;
+ float volume = m_muted ? 0.0f : m_volumeScaled;
for(int j=0; j<dstSample.planes; j++)
{
}
// hook into windowing for receiving display reset events
-#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX)
+#if defined(HAS_GLX) || defined(TARGET_DARWIN)
g_Windowing.Register(this);
#endif
}
}
-bool CActiveAE::SupportsRaw(AEDataFormat format)
+bool CActiveAE::SupportsRaw(AEDataFormat format, int samplerate)
{
- if (!m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), format))
+ if (!m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), format, samplerate))
return false;
return true;
}
else if (settingId == "audiooutput.truehdpassthrough")
{
- if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_TRUEHD) &&
+ if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_TRUEHD, 192000) &&
CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED)
return true;
}
else if (settingId == "audiooutput.dtshdpassthrough")
{
- if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_DTSHD) &&
+ if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_DTSHD, 192000) &&
CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED)
return true;
}
else if (settingId == "audiooutput.eac3passthrough")
{
- if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_EAC3) &&
+ if (m_sink.SupportsFormat(CSettings::Get().GetString("audiooutput.passthroughdevice"), AE_FMT_EAC3, 192000) &&
CSettings::Get().GetInt("audiooutput.config") != AE_CONFIG_FIXED)
return true;
}
IAEStream *CActiveAE::MakeStream(enum AEDataFormat dataFormat, unsigned int sampleRate, unsigned int encodedSampleRate, CAEChannelInfo channelLayout, unsigned int options)
{
+ if (IsSuspended())
+ return NULL;
+
//TODO: pass number of samples in audio packet
AEAudioFormat format;