/* This file is part of the KDE project. Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 or 3 of the License. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #import #include "mediaobjectaudionode.h" #include "quicktimeaudioplayer.h" #include "quicktimevideoplayer.h" #include "audiomixer.h" QT_BEGIN_NAMESPACE namespace Phonon { namespace QT7 { MediaObjectAudioNode::MediaObjectAudioNode(QuickTimeAudioPlayer *player1, QuickTimeAudioPlayer *player2) : AudioNode(0, 1) { m_mute = false; m_player1 = player1; m_player2 = player2; m_mixer = new AudioMixerAudioNode(); m_connection1 = new AudioConnection(m_player1, 0, m_mixer, 0); m_connection2 = new AudioConnection(m_player2, 0, m_mixer, 1); m_fadeDuration = 0; } MediaObjectAudioNode::~MediaObjectAudioNode() { setGraph(0); delete m_player1; delete m_player2; delete m_mixer; delete m_connection1; delete m_connection2; } void MediaObjectAudioNode::createAndConnectAUNodes() { DEBUG_AUDIO_GRAPH("(MediaObjectAudioNode" << int(this) << "createAndConnectAUNodes called)" ) m_player1->createAndConnectAUNodes(); m_player2->createAndConnectAUNodes(); m_mixer->createAndConnectAUNodes(); m_connection1->connect(m_audioGraph); m_connection2->connect(m_audioGraph); } void MediaObjectAudioNode::createAudioUnits() { DEBUG_AUDIO_GRAPH("(MediaObjectAudioNode" << int(this) << "createAudioUnits called)" ) m_player1->createAudioUnits(); m_player2->createAudioUnits(); m_mixer->createAudioUnits(); } void MediaObjectAudioNode::setGraph(AudioGraph *audioGraph) { DEBUG_AUDIO_GRAPH("MediaObjectAudioNode" << int(this) << "is setting graph:" << int(audioGraph)) m_audioGraph = audioGraph; m_player1->setGraph(audioGraph); m_player2->setGraph(audioGraph); m_mixer->setGraph(audioGraph); } AUNode MediaObjectAudioNode::getOutputAUNode() { return m_mixer->getOutputAUNode(); } bool MediaObjectAudioNode::fillInStreamSpecification(AudioConnection *connection, ConnectionSide side) { if (side == Source){ DEBUG_AUDIO_STREAM("(MediaObjectAudioNode" << int(this) << "fillInStreamSpecification called, role = source)") return m_mixer->fillInStreamSpecification(connection, side); } else { DEBUG_AUDIO_STREAM("(MediaObjectAudioNode" << int(this) << "fillInStreamSpecification called, role = sink)") return (m_connection2->updateStreamSpecification() && m_connection1->updateStreamSpecification()); } } bool MediaObjectAudioNode::setStreamSpecification(AudioConnection *connection, ConnectionSide side) { if (side == Source){ DEBUG_AUDIO_STREAM("(MediaObjectAudioNode" << int(this) << "setStreamSpecification called, role = source)") return m_mixer->setStreamSpecification(connection, side); } return true; } void MediaObjectAudioNode::setMute(bool mute) { m_mute = mute; m_mixer->setVolume(m_mute ? 0 : m_volume1, m_connection1->m_sinkInputBus); m_mixer->setVolume(m_mute ? 0 : m_volume2, m_connection2->m_sinkInputBus); } void MediaObjectAudioNode::updateVolume() { if (m_mute) return; QuickTimeVideoPlayer *player1 = static_cast(m_connection1->m_sourceAudioNode)->videoPlayer(); QuickTimeVideoPlayer *player2 = static_cast(m_connection2->m_sourceAudioNode)->videoPlayer(); if (player1) player1->setRelativeVolume(m_volume1); if (player2) player2->setRelativeVolume(m_volume2); m_mixer->setVolume(m_volume1, m_connection1->m_sinkInputBus); m_mixer->setVolume(m_volume2, m_connection2->m_sinkInputBus); } void MediaObjectAudioNode::startCrossFade(qint64 duration) { m_fadeDuration = duration; // Swap: AudioConnection *tmp = m_connection1; m_connection1 = m_connection2; m_connection2 = tmp; // Init volume: if (m_fadeDuration > 0){ m_volume1 = 0; m_volume2 = 1; } else { m_volume1 = 1; m_volume2 = 0; } updateVolume(); } float MediaObjectAudioNode::applyCurve(float volume) { float newValue = 0; if (volume > 0) newValue = float(0.5f * (2 + log10(volume))); return newValue; } void MediaObjectAudioNode::updateCrossFade(qint64 currentTime) { // Assume that currentTime starts at 0 and progress. if (m_fadeDuration > 0){ float volume = float(currentTime) / float(m_fadeDuration); if (volume >= 1){ volume = 1; m_fadeDuration = 0; } m_volume1 = applyCurve(volume); m_volume2 = 1 - volume; updateVolume(); } } bool MediaObjectAudioNode::isCrossFading() { return (m_fadeDuration > 0); } void MediaObjectAudioNode::cancelCrossFade() { m_fadeDuration = 0; m_volume1 = 1; m_volume2 = 0; updateVolume(); } void MediaObjectAudioNode::mediaNodeEvent(const MediaNodeEvent *event) { switch (event->type()){ case MediaNodeEvent::AudioGraphAboutToBeDeleted: m_connection1->invalidate(); m_connection2->invalidate(); break; case MediaNodeEvent::AudioGraphCannotPlay: case MediaNodeEvent::AudioGraphInitialized: updateVolume(); break; default: break; } m_player1->mediaNodeEvent(event); m_player2->mediaNodeEvent(event); m_mixer->mediaNodeEvent(event); } }} //namespace Phonon::QT7 QT_END_NAMESPACE