Ejemplo n.º 1
0
void EngineMaster::processChannels(unsigned int* busChannelConnectionFlags,
                                   unsigned int* headphoneOutput,
                                   int iBufferSize) {
    ScopedTimer timer("EngineMaster::processChannels");

    QList<ChannelInfo*>::iterator it = m_channels.begin();
    QList<ChannelInfo*>::iterator master_it = NULL;

    // Clear talkover compressor for the next round of gain calculation.
    m_pTalkoverDucking->clearKeys();

    // Find the Sync Master and process it first then process all the slaves
    // (and skip the master).

    EngineChannel* pMasterChannel = m_pMasterSync->getMaster();
    if (pMasterChannel != NULL) {
        for (unsigned int channel_number = 0;
             it != m_channels.end(); ++it, ++channel_number) {
            ChannelInfo* pChannelInfo = *it;
            EngineChannel* pChannel = pChannelInfo->m_pChannel;
            if (!pChannel || !pChannel->isActive()) {
               continue;
            }

            if (pMasterChannel == pChannel) {
                master_it = it;

                // Proceed with the processing as below.
                bool needsProcessing = false;
                if (pChannel->isMaster()) {
                    busChannelConnectionFlags[pChannel->getOrientation()] |= (1 << channel_number);
                    needsProcessing = true;
                }

                // If the channel is enabled for previewing in headphones, copy it
                // over to the headphone buffer
                if (pChannel->isPFL()) {
                    *headphoneOutput |= (1 << channel_number);
                    needsProcessing = true;
                }

                // Process the buffer if necessary, which it damn well better be
                if (needsProcessing) {
                    pChannel->process(pChannelInfo->m_pBuffer, iBufferSize);

                    if (m_pTalkoverDucking->getMode() != EngineTalkoverDucking::OFF &&
                            pChannel->isTalkover()) {
                        m_pTalkoverDucking->processKey(pChannelInfo->m_pBuffer, iBufferSize);
                    }
                }
                break;
            }
        }
    }

    it = m_channels.begin();
    for (unsigned int channel_number = 0;
         it != m_channels.end(); ++it, ++channel_number) {
        ChannelInfo* pChannelInfo = *it;
        EngineChannel* pChannel = pChannelInfo->m_pChannel;

        // Skip the master since we already processed it.
        if (it == master_it) {
            continue;
        }

        // Skip inactive channels.
        if (!pChannel || !pChannel->isActive()) {
            continue;
        }

        bool needsProcessing = false;
        if (pChannel->isMaster()) {
            busChannelConnectionFlags[pChannel->getOrientation()] |= (1 << channel_number);
            needsProcessing = true;
        }

        // If the channel is enabled for previewing in headphones, copy it
        // over to the headphone buffer
        if (pChannel->isPFL()) {
            *headphoneOutput |= (1 << channel_number);
            needsProcessing = true;
        }

        // Process the buffer if necessary
        if (needsProcessing) {
            pChannel->process(pChannelInfo->m_pBuffer, iBufferSize);

            if (m_pTalkoverDucking->getMode() != EngineTalkoverDucking::OFF &&
                    pChannel->isTalkover()) {
                m_pTalkoverDucking->processKey(pChannelInfo->m_pBuffer, iBufferSize);
            }
        }
    }
}
Ejemplo n.º 2
0
void EngineMaster::processChannels(int iBufferSize) {
    m_activeBusChannels[EngineChannel::LEFT].clear();
    m_activeBusChannels[EngineChannel::CENTER].clear();
    m_activeBusChannels[EngineChannel::RIGHT].clear();
    m_activeHeadphoneChannels.clear();
    m_activeTalkoverChannels.clear();
    m_activeChannels.clear();

    ScopedTimer timer("EngineMaster::processChannels");
    EngineChannel* pMasterChannel = m_pMasterSync->getMaster();
    // Reserve the first place for the master channel which
    // should be processed first
    m_activeChannels.append(NULL);
    int activeChannelsStartIndex = 1; // Nothing at 0 yet
    for (int i = 0; i < m_channels.size(); ++i) {
        ChannelInfo* pChannelInfo = m_channels[i];
        EngineChannel* pChannel = pChannelInfo->m_pChannel;

        // Skip inactive channels.
        if (!pChannel || !pChannel->isActive()) {
            continue;
        }

        if (pChannel->isTalkoverEnabled()) {
            // talkover is an exclusive channel
            // once talkover is enabled it is not used in
            // xFader-Mix
            m_activeTalkoverChannels.append(pChannelInfo);

            // Check if we need to fade out the master channel
            GainCache& gainCache = m_channelMasterGainCache[i];
            if (gainCache.m_gain) {
                gainCache.m_fadeout = true;
                m_activeBusChannels[pChannel->getOrientation()].append(pChannelInfo);
             }
        } else {
            // Check if we need to fade out the channel
            GainCache& gainCache = m_channelTalkoverGainCache[i];
            if (gainCache.m_gain) {
                gainCache.m_fadeout = true;
                m_activeTalkoverChannels.append(pChannelInfo);
            }
            if (pChannel->isMasterEnabled() &&
                    !pChannelInfo->m_pMuteControl->toBool()) {
                // the xFader-Mix
                m_activeBusChannels[pChannel->getOrientation()].append(pChannelInfo);
            } else {
                // Check if we need to fade out the channel
                GainCache& gainCache = m_channelMasterGainCache[i];
                if (gainCache.m_gain) {
                    gainCache.m_fadeout = true;
                    m_activeBusChannels[pChannel->getOrientation()].append(pChannelInfo);
                }
            }
        }

        // If the channel is enabled for previewing in headphones, copy it
        // over to the headphone buffer
        if (pChannel->isPflEnabled()) {
            m_activeHeadphoneChannels.append(pChannelInfo);
        } else {
            // Check if we need to fade out the channel
            GainCache& gainCache = m_channelHeadphoneGainCache[i];
            if (gainCache.m_gain) {
                m_channelHeadphoneGainCache[i].m_fadeout = true;
                m_activeHeadphoneChannels.append(pChannelInfo);
            }
        }

        // If necessary, add the channel to the list of buffers to process.
        if (pChannel == pMasterChannel) {
            // If this is the sync master, it should be processed first.
            m_activeChannels.replace(0, pChannelInfo);
            activeChannelsStartIndex = 0;
        } else {
            m_activeChannels.append(pChannelInfo);
        }
    }

    // Now that the list is built and ordered, do the processing.
    for (int i = activeChannelsStartIndex;
             i < m_activeChannels.size(); ++i) {
        ChannelInfo* pChannelInfo = m_activeChannels[i];
        EngineChannel* pChannel = pChannelInfo->m_pChannel;
        pChannel->process(pChannelInfo->m_pBuffer, iBufferSize);
    }

    // After all the engines have been processed, trigger post-processing
    // which ensures that all channels are updating certain values at the
    // same point in time.  This prevents sync from failing depending on
    // if the sync target was processed before or after the sync origin.
    for (int i = activeChannelsStartIndex;
            i < m_activeChannels.size(); ++i) {
        m_activeChannels[i]->m_pChannel->postProcess(iBufferSize);
    }
}