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 "audiooutput.h"
19
#include "audiograph.h"
20
#include "audiodevice.h"
21
#include "mediaobject.h"
22
23
QT_BEGIN_NAMESPACE
24
25
namespace Phonon
26
{
27
namespace QT7
28
{
29
30
AudioOutputAudioPart::AudioOutputAudioPart() : AudioNode(1, 0)
31
{
32
    m_audioDevice = AudioDevice::defaultDevice(AudioDevice::Out);
33
    m_volume = 1;
34
}
35
36
ComponentDescription AudioOutputAudioPart::getAudioNodeDescription() const
37
{
38
	ComponentDescription description;
39
	description.componentType = kAudioUnitType_Output;
40
	description.componentSubType = kAudioUnitSubType_DefaultOutput;
41
	description.componentManufacturer = kAudioUnitManufacturer_Apple;
42
	description.componentFlags = 0;
43
	description.componentFlagsMask = 0;
44
    return description;
45
}
46
47
void AudioOutputAudioPart::initializeAudioUnit()
48
{
49
    setAudioDevice(m_audioDevice);
50
    setVolume(m_volume);
51
}
52
53
void AudioOutputAudioPart::setAudioDevice(AudioDeviceID device)
54
{
55
    m_audioDevice = device;
56
    if (!m_audioDevice)
57
        return;
58
    if (!m_audioUnit)
59
        return;
60
    bool ok = AudioDevice::setDevice(m_audioUnit, m_audioDevice, AudioDevice::Out);
61
    if (!ok)
62
        emit audioDeviceFailed();
63
}
64
65
void AudioOutputAudioPart::setVolume(float volume)
66
{
67
    if (volume < 0)
68
        m_volume = 0;
69
    if (volume > 1)
70
        m_volume = 1;
71
    else
72
        m_volume = volume;
73
74
    if (m_audioUnit){
75
        float db = volume;//20.0 * log10(volume); // convert to db
76
        OSStatus err = AudioUnitSetParameter(m_audioUnit, kHALOutputParam_Volume, kAudioUnitScope_Input, 0, db, 0);
77
        BACKEND_ASSERT2(err == noErr, "Could not set volume on output audio unit.", FATAL_ERROR)
78
        emit volumeChanged(qreal(db));
79
    }
80
}
81
82
float AudioOutputAudioPart::volume()
83
{
84
    return m_volume;
85
}
86
87
////////////////////////////////////////////////////////////////////////////////////////
88
89
AudioOutput::AudioOutput(QObject *parent) : MediaNode(AudioSink, parent)
90
{
91
    m_audioOutput = new AudioOutputAudioPart();
92
    setAudioNode(m_audioOutput);
93
    connect(m_audioOutput, SIGNAL(volumeChanged(qreal)), this, SIGNAL(volumeChanged(qreal)));
94
    connect(m_audioOutput, SIGNAL(audioDeviceFailed()), this, SIGNAL(audioDeviceFailed()));
95
    m_redirectToMovie = false;
96
}
97
98
AudioOutput::~AudioOutput()
99
{
100
}
101
102
void AudioOutput::setVolume(qreal volume)
103
{
104
    IMPLEMENTED;
105
    m_audioOutput->setVolume(float(volume));
106
    if (m_owningMediaObject)
107
       m_owningMediaObject->setVolumeOnMovie(volume);
108
        
109
    emit volumeChanged(m_audioOutput->volume());
110
}
111
112
qreal AudioOutput::volume() const
113
{
114
    IMPLEMENTED;
115
    return qreal(m_audioOutput->volume());
116
}
117
118
bool AudioOutput::setOutputDevice(int device)
119
{
120
    IMPLEMENTED;
121
    if (device == -1)
122
        return false;
123
124
    if (m_owningMediaObject){
125
        bool ok = m_owningMediaObject->setAudioDeviceOnMovie(device);
126
        if (!ok)
127
            return false;
128
    }
129
    
130
    if (m_audioGraph){
131
        MediaNodeEvent event1(MediaNodeEvent::AboutToRestartAudioStream, this);
132
        m_audioGraph->notify(&event1);
133
    }
134
    
135
    m_audioOutput->setAudioDevice(device);
136
    
137
    if (m_audioGraph){
138
        MediaNodeEvent event2(MediaNodeEvent::RestartAudioStreamRequest, this);
139
        m_audioGraph->notify(&event2);
140
    }
141
    return true;
142
}
143
144
int AudioOutput::outputDevice() const
145
{
146
    IMPLEMENTED;
147
    return m_audioOutput->m_audioDevice;
148
}
149
150
void AudioOutput::mediaNodeEvent(const MediaNodeEvent *event)
151
{
152
    switch (event->type()){
153
        case MediaNodeEvent::SetMediaObject:
154
            if (static_cast<MediaObject *>(event->data())){
155
                setVolume(volume());
156
                setOutputDevice(outputDevice());
157
            }
158
            break;
159
        default:
160
            break;
161
    }
162
}
163
164
}} //namespace Phonon::QT7
165
166
QT_END_NAMESPACE
167
168
#include "moc_audiooutput.cpp"