~ubuntu-branches/ubuntu/oneiric/phonon/oneiric-201108111512

« back to all changes in this revision

Viewing changes to qt7/audionode.mm

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2011-01-24 10:12:11 UTC
  • mfrom: (0.5.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110124101211-w9rew7q0dmwbwhqx
Tags: 4:4.7.0really4.4.4-0ubuntu1
* New upstream release
* Xine and GStreamer backends now split out source, remove build-deps and
  binary packages from debian/control
* Remove 02_no_rpath.patch, now upstream
* Disable kubuntu04_no_va_mangle.patch, no longer applies
* Remove kubuntu_05_gst_codec_installer_window_id.diff, kubuntu_06_forward_events.diff,
  kubuntu_07_include_fix.diff, gstreamer now separate

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "audionode.h"
19
 
#include "audiograph.h"
20
 
#include "audioconnection.h"
21
 
#include "medianode.h"
22
 
 
23
 
QT_BEGIN_NAMESPACE
24
 
 
25
 
namespace Phonon
26
 
{
27
 
namespace QT7
28
 
{
29
 
 
30
 
AudioNode::AudioNode(int maxInputBusses, int maxOutputBusses)
31
 
{
32
 
    m_auNode = 0;
33
 
    m_audioUnit = 0;
34
 
    m_audioGraph = 0;
35
 
    m_maxInputBusses = maxInputBusses;
36
 
    m_maxOutputBusses = maxOutputBusses;
37
 
    m_lastConnectionIn = 0;
38
 
}
39
 
 
40
 
AudioNode::~AudioNode()
41
 
{
42
 
    setGraph(0);
43
 
}
44
 
 
45
 
void AudioNode::setGraph(AudioGraph *audioGraph)
46
 
{
47
 
    if (m_audioGraph == audioGraph)
48
 
        return;
49
 
 
50
 
    DEBUG_AUDIO_GRAPH("AudioNode" << int(this) << "is setting graph:" << int(audioGraph))    
51
 
    if (m_auNode){
52
 
        AUGraphRemoveNode(m_audioGraph->audioGraphRef(), m_auNode);
53
 
        m_auNode = 0;
54
 
    }
55
 
    
56
 
    m_audioUnit = 0;
57
 
    m_lastConnectionIn = 0;
58
 
    m_audioGraph = audioGraph;
59
 
}
60
 
 
61
 
void AudioNode::createAndConnectAUNodes()
62
 
{
63
 
    if (m_auNode)
64
 
        return;
65
 
 
66
 
    ComponentDescription description = getAudioNodeDescription();
67
 
    DEBUG_AUDIO_GRAPH("AudioNode" << int(this) << "creates AUNode" 
68
 
        << QString(!FindNextComponent(0, &description) ? "ERROR: COMPONENT NOT FOUND!" : "OK!"))
69
 
 
70
 
    OSStatus err = noErr;
71
 
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
72
 
    if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
73
 
        err = AUGraphAddNode(m_audioGraph->audioGraphRef(), &description, &m_auNode);
74
 
    else
75
 
#endif
76
 
        err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode);
77
 
        
78
 
    BACKEND_ASSERT2(err != kAUGraphErr_OutputNodeErr, "A MediaObject can only be connected to one audio output device.", FATAL_ERROR)
79
 
    BACKEND_ASSERT2(err == noErr, "Could not create new AUNode.", FATAL_ERROR)
80
 
}
81
 
 
82
 
AUNode AudioNode::getInputAUNode()
83
 
{
84
 
    return m_auNode;
85
 
}
86
 
 
87
 
AUNode AudioNode::getOutputAUNode()
88
 
{
89
 
    return m_auNode;
90
 
}
91
 
 
92
 
void AudioNode::createAudioUnits()
93
 
{
94
 
    if (m_audioUnit)
95
 
        return;
96
 
 
97
 
    DEBUG_AUDIO_GRAPH("AudioNode" << int(this) << "creates AudioUnit")
98
 
    OSStatus err = AUGraphGetNodeInfo(m_audioGraph->audioGraphRef(), m_auNode, 0, 0, 0, &m_audioUnit);
99
 
    BACKEND_ASSERT2(err == noErr, "Could not get audio unit from audio node.", FATAL_ERROR)
100
 
    initializeAudioUnit();
101
 
}
102
 
 
103
 
ComponentDescription AudioNode::getAudioNodeDescription() const
104
 
{
105
 
    // Override if needed.
106
 
    ComponentDescription cd;
107
 
    Q_UNUSED(cd);
108
 
    return cd;
109
 
}
110
 
 
111
 
bool AudioNode::setStreamHelp(AudioConnection *c, int bus, OSType scope, bool fromSource)
112
 
{
113
 
    if (fromSource){
114
 
            OSStatus err = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, scope,
115
 
                bus, &c->m_sourceStreamDescription, sizeof(AudioStreamBasicDescription));
116
 
        if (err != noErr){
117
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << " - failed setting stream format")
118
 
            return false;
119
 
        }
120
 
            AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_AudioChannelLayout, scope,
121
 
            bus, c->m_sourceChannelLayout, c->m_sourceChannelLayoutSize);
122
 
    } else {
123
 
            OSStatus err = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, scope,
124
 
                bus, &c->m_sinkStreamDescription, sizeof(AudioStreamBasicDescription));
125
 
        if (err != noErr){
126
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << " - failed setting stream format")
127
 
            return false;
128
 
        }
129
 
            AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_AudioChannelLayout, scope,
130
 
            bus, c->m_sinkChannelLayout, c->m_sourceChannelLayoutSize);
131
 
    }
132
 
    return true;
133
 
}
134
 
 
135
 
bool AudioNode::setStreamSpecification(AudioConnection *connection, ConnectionSide side)
136
 
{
137
 
    if (side == Source){
138
 
        // This object am source of connection:
139
 
        if (connection->m_hasSourceSpecification){
140
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "sets stream specification out"
141
 
                << connection->m_sourceOutputBus << "from connection source")
142
 
            return setStreamHelp(connection, connection->m_sourceOutputBus, kAudioUnitScope_Output, true);
143
 
        } else {
144
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "did not set stream specification out")
145
 
        }
146
 
    } else {
147
 
        if (connection->m_hasSinkSpecification){
148
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "sets stream specification"
149
 
                << connection->m_sinkInputBus << "from connection sink")
150
 
            return setStreamHelp(connection, connection->m_sinkInputBus, kAudioUnitScope_Input, false);
151
 
        } else if (connection->m_hasSourceSpecification){
152
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "sets stream specification"
153
 
            << connection->m_sinkInputBus << "from connection source")
154
 
            return setStreamHelp(connection, connection->m_sinkInputBus, kAudioUnitScope_Input, true);
155
 
        } else {
156
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "did not set stream specification in")
157
 
        }
158
 
    }
159
 
    return true;
160
 
}
161
 
 
162
 
bool AudioNode::fillInStreamSpecification(AudioConnection *connection, ConnectionSide side)
163
 
{
164
 
    if (side == Source){
165
 
        // As default, use the last description to describe the source:
166
 
        if (m_lastConnectionIn->m_hasSinkSpecification){
167
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "is source, and fills in stream spec using last connection sink.")
168
 
            connection->m_sourceStreamDescription = m_lastConnectionIn->m_sinkStreamDescription;
169
 
            connection->m_sourceChannelLayout = (AudioChannelLayout *) malloc(m_lastConnectionIn->m_sinkChannelLayoutSize);
170
 
            memcpy(connection->m_sourceChannelLayout, m_lastConnectionIn->m_sinkChannelLayout, m_lastConnectionIn->m_sinkChannelLayoutSize);
171
 
            connection->m_sourceChannelLayoutSize = m_lastConnectionIn->m_sinkChannelLayoutSize;
172
 
            connection->m_hasSourceSpecification = true;
173
 
        } else if (m_lastConnectionIn->m_hasSourceSpecification){
174
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "is source, and fills in stream spec using last connection source.")
175
 
            connection->m_sourceStreamDescription = m_lastConnectionIn->m_sourceStreamDescription;
176
 
            connection->m_sourceChannelLayout = (AudioChannelLayout *) malloc(m_lastConnectionIn->m_sourceChannelLayoutSize);
177
 
            memcpy(connection->m_sourceChannelLayout, m_lastConnectionIn->m_sourceChannelLayout, m_lastConnectionIn->m_sourceChannelLayoutSize);
178
 
            connection->m_sourceChannelLayoutSize = m_lastConnectionIn->m_sourceChannelLayoutSize;
179
 
            connection->m_hasSourceSpecification = true;
180
 
        } else {
181
 
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << " __WARNING__: could not get stream specification...")
182
 
        }
183
 
    } else {
184
 
        DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "is sink, skips filling in stream.")
185
 
        if (!connection->isSinkOnly())
186
 
            m_lastConnectionIn = connection;
187
 
    }
188
 
    return true;
189
 
}
190
 
 
191
 
/**
192
 
    Let timeProperty be one of e.g
193
 
    {kAudioUnitProperty_Latency, kAudioUnitProperty_TailTime,
194
 
    kAudioOutputUnitProperty_StartTime, kAudioUnitProperty_CurrentPlayTime}
195
 
*/
196
 
Float64 AudioNode::getTimeInSamples(int timeProperty)
197
 
{
198
 
    if (!m_audioUnit)
199
 
        return 0;
200
 
 
201
 
    AudioTimeStamp timeStamp;
202
 
    UInt32 size = sizeof(timeStamp);
203
 
    memset(&timeStamp, 0, sizeof(timeStamp));
204
 
        OSStatus err = AudioUnitGetProperty(m_audioUnit,
205
 
        timeProperty, kAudioUnitScope_Global,
206
 
        0, &timeStamp, &size);
207
 
    if (err != noErr)
208
 
        return 0;
209
 
    return timeStamp.mSampleTime;
210
 
}
211
 
 
212
 
void AudioNode::notify(const MediaNodeEvent *event)
213
 
{
214
 
    switch(event->type()){
215
 
    case MediaNodeEvent::AudioGraphAboutToBeDeleted:
216
 
        setGraph(0);
217
 
        break;
218
 
    case MediaNodeEvent::NewAudioGraph:
219
 
        setGraph(static_cast<AudioGraph *>(event->data()));
220
 
        break;
221
 
    default:
222
 
        break;
223
 
    }
224
 
 
225
 
    mediaNodeEvent(event);
226
 
}
227
 
 
228
 
void AudioNode::mediaNodeEvent(const MediaNodeEvent */*event*/)
229
 
{
230
 
    // Override if needed
231
 
}
232
 
 
233
 
void AudioNode::initializeAudioUnit()
234
 
{
235
 
    // Override if needed.
236
 
}
237
 
 
238
 
}} //namespace Phonon::QT7
239
 
 
240
 
QT_END_NAMESPACE