src/3rdparty/phonon/qt7/mediaobjectaudionode.mm
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /*  This file is part of the KDE project.
       
     2 
       
     3     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 
       
     5     This library is free software: you can redistribute it and/or modify
       
     6     it under the terms of the GNU Lesser General Public License as published by
       
     7     the Free Software Foundation, either version 2.1 or 3 of the License.
       
     8 
       
     9     This library is distributed in the hope that it will be useful,
       
    10     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12     GNU Lesser General Public License for more details.
       
    13 
       
    14     You should have received a copy of the GNU Lesser General Public License
       
    15     along with this library.  If not, see <http://www.gnu.org/licenses/>.
       
    16 */
       
    17 
       
    18 #include "mediaobjectaudionode.h"
       
    19 #include "quicktimeaudioplayer.h"
       
    20 #include "quicktimevideoplayer.h"
       
    21 #include "audiomixer.h"
       
    22 
       
    23 QT_BEGIN_NAMESPACE
       
    24 
       
    25 namespace Phonon
       
    26 {
       
    27 namespace QT7
       
    28 {
       
    29 
       
    30 MediaObjectAudioNode::MediaObjectAudioNode(QuickTimeAudioPlayer *player1, QuickTimeAudioPlayer *player2) : AudioNode(0, 1)
       
    31 {
       
    32     m_mute = false;
       
    33     m_player1 = player1;
       
    34     m_player2 = player2;
       
    35     m_mixer = new AudioMixerAudioNode();
       
    36 
       
    37     m_connection1 = new AudioConnection(m_player1, 0, m_mixer, 0);
       
    38     m_connection2 = new AudioConnection(m_player2, 0, m_mixer, 1);
       
    39 
       
    40     m_fadeDuration = 0;
       
    41 }
       
    42 
       
    43 MediaObjectAudioNode::~MediaObjectAudioNode()
       
    44 {
       
    45     setGraph(0);
       
    46     delete m_player1;
       
    47     delete m_player2;
       
    48     delete m_mixer;
       
    49     delete m_connection1;
       
    50     delete m_connection2;
       
    51 }
       
    52 
       
    53 void MediaObjectAudioNode::createAndConnectAUNodes()
       
    54 {
       
    55     DEBUG_AUDIO_GRAPH("(MediaObjectAudioNode" << int(this) << "createAndConnectAUNodes called)" )
       
    56     m_player1->createAndConnectAUNodes();
       
    57     m_player2->createAndConnectAUNodes();
       
    58     m_mixer->createAndConnectAUNodes();
       
    59 
       
    60     m_connection1->connect(m_audioGraph);
       
    61     m_connection2->connect(m_audioGraph);
       
    62 }
       
    63 
       
    64 void MediaObjectAudioNode::createAudioUnits()
       
    65 {
       
    66     DEBUG_AUDIO_GRAPH("(MediaObjectAudioNode" << int(this) << "createAudioUnits called)" )
       
    67     m_player1->createAudioUnits();
       
    68     m_player2->createAudioUnits();
       
    69     m_mixer->createAudioUnits();
       
    70 }
       
    71 
       
    72 void MediaObjectAudioNode::setGraph(AudioGraph *audioGraph)
       
    73 {
       
    74     DEBUG_AUDIO_GRAPH("MediaObjectAudioNode" << int(this) << "is setting graph:" << int(audioGraph))
       
    75     m_audioGraph = audioGraph;
       
    76     m_player1->setGraph(audioGraph);
       
    77     m_player2->setGraph(audioGraph);
       
    78     m_mixer->setGraph(audioGraph);
       
    79 }
       
    80 
       
    81 AUNode MediaObjectAudioNode::getOutputAUNode()
       
    82 {
       
    83     return m_mixer->getOutputAUNode();
       
    84 }
       
    85 
       
    86 bool MediaObjectAudioNode::fillInStreamSpecification(AudioConnection *connection, ConnectionSide side)
       
    87 {
       
    88     if (side == Source){
       
    89         DEBUG_AUDIO_STREAM("(MediaObjectAudioNode" << int(this) << "fillInStreamSpecification called, role = source)")
       
    90         return m_mixer->fillInStreamSpecification(connection, side);
       
    91     } else {
       
    92         DEBUG_AUDIO_STREAM("(MediaObjectAudioNode" << int(this) << "fillInStreamSpecification called, role = sink)")
       
    93         return (m_connection2->updateStreamSpecification() && m_connection1->updateStreamSpecification());
       
    94     }
       
    95 }
       
    96 
       
    97 bool MediaObjectAudioNode::setStreamSpecification(AudioConnection *connection, ConnectionSide side)
       
    98 {
       
    99     if (side == Source){
       
   100         DEBUG_AUDIO_STREAM("(MediaObjectAudioNode" << int(this) << "setStreamSpecification called, role = source)")
       
   101         return m_mixer->setStreamSpecification(connection, side);
       
   102     }
       
   103     return true;
       
   104 }
       
   105 
       
   106 void MediaObjectAudioNode::setMute(bool mute)
       
   107 {
       
   108     m_mute = mute;
       
   109     m_mixer->setVolume(m_mute ? 0 : m_volume1, m_connection1->m_sinkInputBus);
       
   110     m_mixer->setVolume(m_mute ? 0 : m_volume2, m_connection2->m_sinkInputBus);
       
   111 }
       
   112 
       
   113 void MediaObjectAudioNode::updateVolume()
       
   114 {
       
   115     if (m_mute)
       
   116         return;
       
   117         
       
   118     QuickTimeVideoPlayer *player1 = static_cast<QuickTimeAudioPlayer *>(m_connection1->m_sourceAudioNode)->videoPlayer();
       
   119     QuickTimeVideoPlayer *player2 = static_cast<QuickTimeAudioPlayer *>(m_connection2->m_sourceAudioNode)->videoPlayer();
       
   120     if (player1)
       
   121         player1->setRelativeVolume(m_volume1);
       
   122     if (player2)
       
   123         player2->setRelativeVolume(m_volume2);
       
   124 
       
   125     m_mixer->setVolume(m_volume1, m_connection1->m_sinkInputBus);
       
   126     m_mixer->setVolume(m_volume2, m_connection2->m_sinkInputBus);
       
   127 }
       
   128 
       
   129 void MediaObjectAudioNode::startCrossFade(qint64 duration)
       
   130 {
       
   131     m_fadeDuration = duration;
       
   132 
       
   133     // Swap:
       
   134     AudioConnection *tmp = m_connection1;
       
   135     m_connection1 = m_connection2;
       
   136     m_connection2 = tmp;
       
   137 
       
   138     // Init volume:
       
   139     if (m_fadeDuration > 0){
       
   140         m_volume1 = 0;
       
   141         m_volume2 = 1;
       
   142     } else {
       
   143         m_volume1 = 1;
       
   144         m_volume2 = 0;
       
   145     }
       
   146     updateVolume();
       
   147 }
       
   148 
       
   149 float MediaObjectAudioNode::applyCurve(float volume)
       
   150 {
       
   151     float newValue = 0;
       
   152     if (volume > 0)
       
   153         newValue = float(0.5f * (2 + log10(volume)));
       
   154     return newValue;
       
   155 }
       
   156 
       
   157 void MediaObjectAudioNode::updateCrossFade(qint64 currentTime)
       
   158 {
       
   159     // Assume that currentTime starts at 0 and progress.
       
   160     if (m_fadeDuration > 0){
       
   161         float volume = float(currentTime) / float(m_fadeDuration);
       
   162         if (volume >= 1){
       
   163             volume = 1;
       
   164             m_fadeDuration = 0;
       
   165         }
       
   166         m_volume1 = applyCurve(volume);
       
   167         m_volume2 = 1 - volume;
       
   168         updateVolume();
       
   169     }
       
   170 }
       
   171 
       
   172 bool MediaObjectAudioNode::isCrossFading()
       
   173 {
       
   174     return (m_fadeDuration > 0);
       
   175 }
       
   176 
       
   177 void MediaObjectAudioNode::cancelCrossFade()
       
   178 {
       
   179     m_fadeDuration = 0;
       
   180     m_volume1 = 1;
       
   181     m_volume2 = 0;
       
   182     updateVolume();
       
   183 }
       
   184 
       
   185 void MediaObjectAudioNode::mediaNodeEvent(const MediaNodeEvent *event)
       
   186 {
       
   187     switch (event->type()){
       
   188     case MediaNodeEvent::AudioGraphAboutToBeDeleted:
       
   189         m_connection1->invalidate();
       
   190         m_connection2->invalidate();
       
   191         break;
       
   192     case MediaNodeEvent::AudioGraphCannotPlay:
       
   193     case MediaNodeEvent::AudioGraphInitialized:
       
   194         updateVolume();
       
   195         break;
       
   196     default:
       
   197         break;
       
   198     }
       
   199 
       
   200     m_player1->mediaNodeEvent(event);
       
   201     m_player2->mediaNodeEvent(event);
       
   202     m_mixer->mediaNodeEvent(event);
       
   203 }
       
   204 
       
   205 }} //namespace Phonon::QT7
       
   206 
       
   207 QT_END_NAMESPACE