X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=xbmc%2Fcores%2FAudioEngine%2FEngines%2FActiveAE%2FActiveAE.cpp;h=eae62530dd815d94ead2345ad0f80ca6d8cfa2df;hb=35b5f279740b89321e8be3a6d80ef10eeed5748e;hp=c871ee893e978b781dbe6171d0c2d30818bd4394;hpb=5e111e741ec7563a57a979f990d095145abf6c2e;p=vuplus_xbmc diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index c871ee8..eae6253 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -32,6 +32,7 @@ using namespace ActiveAE; #define MAX_CACHE_LEVEL 0.5 // total cache time of stream in seconds #define MAX_WATER_LEVEL 0.25 // buffered time after stream stages in seconds +#define MAX_BUFFER_TIME 0.1 // max time of a buffer in seconds void CEngineStats::Reset(unsigned int sampleRate) { @@ -101,7 +102,7 @@ float CEngineStats::GetDelay(CActiveAEStream *stream) if (delay < 0) delay = 0.0; - delay += stream->m_bufferedTime; + delay += stream->m_bufferedTime / stream->m_streamResampleRatio; return delay; } @@ -121,6 +122,7 @@ float CEngineStats::GetCacheTotal(CActiveAEStream *stream) float CEngineStats::GetWaterLevel() { + CSingleLock lock(m_lock); return (float)m_bufferedSamples / m_sinkSampleRate; } @@ -148,6 +150,7 @@ CActiveAE::CActiveAE() : m_vizBuffers = NULL; m_vizBuffersInput = NULL; m_volume = 1.0; + m_volumeScaled = 1.0; m_aeVolume = 1.0; m_muted = false; m_aeMuted = false; @@ -165,7 +168,7 @@ CActiveAE::~CActiveAE() void CActiveAE::Dispose() { -#if defined(HAS_GLX) || defined(TARGET_DARWIN_OSX) +#if defined(HAS_GLX) || defined(TARGET_DARWIN) g_Windowing.Unregister(this); #endif @@ -224,6 +227,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) 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; @@ -235,6 +239,9 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) return; case CActiveAEControlProtocol::DISPLAYRESET: return; + case CActiveAEControlProtocol::APPFOCUSED: + m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::APPFOCUSED, msg->data, sizeof(bool)); + return; default: break; } @@ -392,13 +399,14 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) case AE_TOP_CONFIGURED: if (port == &m_controlPort) { + bool streaming; switch (signal) { case CActiveAEControlProtocol::RECONFIGURE: if (m_streams.empty()) { - bool silence = false; - m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::SILENCEMODE, &silence, sizeof(bool)); + streaming = false; + m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::STREAMING, &streaming, sizeof(bool)); } LoadSettings(); ChangeResamplers(); @@ -428,6 +436,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) 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(); @@ -439,6 +448,7 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) } m_extLastDeviceChange.push(now); UnconfigureSink(); + m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE); m_sink.EnumerateSinkList(true); LoadSettings(); m_extError = false; @@ -453,18 +463,23 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) m_state = AE_TOP_ERROR; m_extTimeout = 500; } - m_controlPort.PurgeOut(CActiveAEControlProtocol::DEVICECHANGE); return; case CActiveAEControlProtocol::PAUSESTREAM: CActiveAEStream *stream; stream = *(CActiveAEStream**)msg->data; if (stream->m_paused != true && m_streams.size() == 1) + { FlushEngine(); + streaming = false; + m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::STREAMING, &streaming, sizeof(bool)); + } stream->m_paused = true; return; case CActiveAEControlProtocol::RESUMESTREAM: stream = *(CActiveAEStream**)msg->data; stream->m_paused = false; + streaming = true; + m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::STREAMING, &streaming, sizeof(bool)); m_extTimeout = 0; return; case CActiveAEControlProtocol::FLUSHSTREAM: @@ -621,11 +636,13 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) 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(); } @@ -645,6 +662,8 @@ void CActiveAE::StateMachine(int signal, Protocol *port, Message *msg) m_stats.SetSuspended(false); m_extDeferData = false; return; + case CActiveAEControlProtocol::DEVICECHANGE: + return; default: break; } @@ -942,11 +961,11 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::VOLUME, &m_volume, sizeof(float)); // limit buffer size in case of sink returns large buffer - unsigned int buffertime = (m_sinkFormat.m_frames*1000) / m_sinkFormat.m_sampleRate; - if (buffertime > 80) + 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 80 ms", __FUNCTION__, buffertime); - m_sinkFormat.m_frames = 80 * m_sinkFormat.m_sampleRate / 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; } } @@ -973,8 +992,8 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) sinkInputFormat = inputFormat; m_internalFormat = inputFormat; - bool silence = false; - m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::SILENCEMODE, &silence, sizeof(bool)); + bool streaming = false; + m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::STREAMING, &streaming, sizeof(bool)); delete m_encoder; m_encoder = NULL; @@ -998,8 +1017,8 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) // resample buffers for streams else { - bool silence = true; - m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::SILENCEMODE, &silence, sizeof(bool)); + bool streaming = true; + m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::STREAMING, &streaming, sizeof(bool)); AEAudioFormat outputFormat; if (m_mode == MODE_RAW) @@ -1014,6 +1033,7 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) outputFormat = inputFormat; outputFormat.m_dataFormat = AE_FMT_FLOATP; outputFormat.m_sampleRate = 48000; + outputFormat.m_encodedRate = 48000; // setup encoder if (!m_encoder) @@ -1150,7 +1170,9 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt) // 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; @@ -1399,6 +1421,7 @@ void CActiveAE::ApplySettingsToFormat(AEAudioFormat &format, AudioSettings &sett { 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; @@ -1623,13 +1646,15 @@ bool CActiveAE::RunStages() 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 @@ -1722,7 +1747,14 @@ bool CActiveAE::RunStages() 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) { @@ -1952,7 +1984,7 @@ bool CActiveAE::RunStages() 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(); @@ -1961,18 +1993,18 @@ bool CActiveAE::RunStages() } } } + } - // 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; @@ -2051,20 +2083,21 @@ void CActiveAE::MixSounds(CSoundPacket &dstSample) 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_volumeScaled; for(int j=0; j