Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 380161 | Differences between
and this patch

Collapse All | Expand All

(-)mumble-1.2.2.orig/src/mumble/JackAudio.cpp (+314 lines)
Line 0 Link Here
1
/* Copyright (C) 2011, Benjamin Jemlich <pcgod@users.sourceforge.net>
2
   Copyright (C) 2011, Filipe Coelho <falktx@gmail.com>
3
4
   All rights reserved.
5
6
   Redistribution and use in source and binary forms, with or without
7
   modification, are permitted provided that the following conditions
8
   are met:
9
10
   - Redistributions of source code must retain the above copyright notice,
11
     this list of conditions and the following disclaimer.
12
   - Redistributions in binary form must reproduce the above copyright notice,
13
     this list of conditions and the following disclaimer in the documentation
14
     and/or other materials provided with the distribution.
15
   - Neither the name of the Mumble Developers nor the names of its
16
     contributors may be used to endorse or promote products derived from this
17
     software without specific prior written permission.
18
19
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
#include "JackAudio.h"
33
#include "User.h"
34
#include "Global.h"
35
#include "MainWindow.h"
36
#include "Timer.h"
37
38
#include <cstring>
39
40
static JackAudioSystem *jasys = NULL;
41
42
class JackAudioInputRegistrar : public AudioInputRegistrar {
43
        public:
44
                JackAudioInputRegistrar();
45
                virtual AudioInput *create();
46
                virtual const QList<audioDevice> getDeviceChoices();
47
                virtual void setDeviceChoice(const QVariant &, Settings &);
48
                virtual bool canEcho(const QString &) const;
49
};
50
51
class JackAudioOutputRegistrar : public AudioOutputRegistrar {
52
        public:
53
                JackAudioOutputRegistrar();
54
                virtual AudioOutput *create();
55
                virtual const QList<audioDevice> getDeviceChoices();
56
                virtual void setDeviceChoice(const QVariant &, Settings &);
57
};
58
59
class JackAudioInit : public DeferInit {
60
        public:
61
                JackAudioInputRegistrar *airJackAudio;
62
                JackAudioOutputRegistrar *aorJackAudio;
63
                void initialize() {
64
                        jasys = new JackAudioSystem();
65
                        jasys->init_jack();
66
                        jasys->qmWait.lock();
67
                        jasys->qwcWait.wait(&jasys->qmWait, 1000);
68
                        jasys->qmWait.unlock();
69
                        if (jasys->bJackIsGood) {
70
                                airJackAudio = new JackAudioInputRegistrar();
71
                                aorJackAudio = new JackAudioOutputRegistrar();
72
                        } else {
73
                                airJackAudio = NULL;
74
                                aorJackAudio = NULL;
75
                                delete jasys;
76
                                jasys = NULL;
77
                        }
78
                };
79
                void destroy() {
80
                        if (airJackAudio)
81
                                delete airJackAudio;
82
                        if (aorJackAudio)
83
                                delete aorJackAudio;
84
                        if (jasys) {
85
                                jasys->close_jack();
86
                                delete jasys;
87
                                jasys = NULL;
88
                        }
89
                };
90
};
91
92
static JackAudioInit jackinit; //unused
93
94
JackAudioSystem::JackAudioSystem() {
95
        bJackIsGood = false;
96
        iSampleRate = 0;
97
}
98
99
JackAudioSystem::~JackAudioSystem() {
100
}
101
102
void JackAudioSystem::init_jack()
103
{
104
        client = jack_client_open("mumble", JackNullOption, 0);
105
106
        if (client) {
107
                in_port = jack_port_register(client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
108
                out_port = jack_port_register(client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
109
                jack_set_process_callback(client, process_callback, this);
110
                jack_set_sample_rate_callback(client, srate_callback, this);
111
                jack_on_shutdown(client, shutdown_callback, this);
112
113
                iSampleRate = jack_get_sample_rate(client);
114
115
                if (jack_activate(client) || in_port == NULL || out_port == NULL) {
116
                    client = NULL;
117
                    return;
118
                }
119
120
                int port_flags;
121
                unsigned i = -1;
122
                const char** ports = jack_get_ports(client, 0, 0, JackPortIsPhysical);
123
124
                if (ports) {
125
                    while (ports[++i])
126
                    {
127
                        jack_port_t* port = jack_port_by_name(client, ports[i]);
128
                        port_flags = jack_port_flags(port);
129
130
                        if (port_flags & (JackPortIsPhysical|JackPortIsOutput) && strstr(jack_port_type(port), "audio")) {
131
                            jack_connect(client, ports[i], jack_port_name(in_port));
132
                        }
133
                        if (port_flags & (JackPortIsPhysical|JackPortIsInput) && strstr(jack_port_type(port), "audio")) {
134
                            jack_connect(client, jack_port_name(out_port), ports[i]);
135
                        }
136
                    }
137
                }
138
139
                jack_free(ports);
140
141
                // If we made it this far, then everything is okay
142
                qhInput.insert(QString(), tr("Hardware Ports"));
143
                qhOutput.insert(QString(), tr("Hardware Ports"));
144
                bJackIsGood = true;
145
146
            } else {
147
                bJackIsGood = false;
148
                client = NULL;
149
            }
150
}
151
152
void JackAudioSystem::close_jack()
153
{
154
        if (client) {
155
                jack_deactivate(client);
156
                jack_client_close(client);
157
                client = NULL;
158
        }
159
}
160
161
int JackAudioSystem::process_callback(jack_nframes_t nframes, void *arg)
162
{
163
        JackAudioSystem *jas = (JackAudioSystem*)arg;
164
165
        if (jas && jas->bJackIsGood) {
166
                AudioInputPtr ai = g.ai;
167
                AudioOutputPtr ao = g.ao;
168
                JackAudioInput *jai = (JackAudioInput*)(ai.get());
169
                JackAudioOutput *jao = (JackAudioOutput*)(ao.get());
170
171
                if (jai && jai->bRunning && jai->iMicChannels > 0 && !jai->isFinished()) {
172
                        void* input = jack_port_get_buffer(jas->in_port, nframes);
173
                        if ((float*)input != 0)
174
                            jai->addMic(input, nframes);
175
                }
176
177
                if (jao && jao->bRunning && jao->iChannels > 0 && !jao->isFinished()) {
178
                        jack_default_audio_sample_t* output = (jack_default_audio_sample_t*)jack_port_get_buffer(jas->out_port, nframes);
179
                        memset(output, 0, sizeof(jack_default_audio_sample_t)*nframes); //TEST
180
                        jao->mix(output, nframes);
181
                }
182
        }
183
184
        return 0;
185
}
186
187
int JackAudioSystem::srate_callback(jack_nframes_t frames, void *arg)
188
{
189
        JackAudioSystem *jas = (JackAudioSystem*)arg;
190
        jas->iSampleRate = frames;
191
        return 0;
192
}
193
194
void JackAudioSystem::shutdown_callback(void *arg)
195
{
196
        JackAudioSystem *jas = (JackAudioSystem*)arg;
197
        jas->bJackIsGood = false;
198
}
199
200
JackAudioInputRegistrar::JackAudioInputRegistrar() : AudioInputRegistrar(QLatin1String("JACK"), 10) {
201
}
202
203
AudioInput *JackAudioInputRegistrar::create() {
204
        return new JackAudioInput();
205
}
206
207
const QList<audioDevice> JackAudioInputRegistrar::getDeviceChoices() {
208
        QList<audioDevice> qlReturn;
209
210
        QStringList qlInputDevs = jasys->qhInput.keys();
211
        qSort(qlInputDevs);
212
213
        foreach(const QString &dev, qlInputDevs) {
214
                qlReturn << audioDevice(jasys->qhInput.value(dev), dev);
215
        }
216
217
        return qlReturn;
218
}
219
220
void JackAudioInputRegistrar::setDeviceChoice(const QVariant &choice, Settings &s) {
221
        Q_UNUSED(choice);
222
        Q_UNUSED(s);
223
}
224
225
bool JackAudioInputRegistrar::canEcho(const QString &osys) const {
226
        Q_UNUSED(osys);
227
        return false;
228
}
229
230
JackAudioOutputRegistrar::JackAudioOutputRegistrar() : AudioOutputRegistrar(QLatin1String("JACK"), 10) {
231
}
232
233
AudioOutput *JackAudioOutputRegistrar::create() {
234
        return new JackAudioOutput();
235
}
236
237
const QList<audioDevice> JackAudioOutputRegistrar::getDeviceChoices() {
238
        QList<audioDevice> qlReturn;
239
240
        QStringList qlOutputDevs = jasys->qhOutput.keys();
241
        qSort(qlOutputDevs);
242
243
        foreach(const QString &dev, qlOutputDevs) {
244
                qlReturn << audioDevice(jasys->qhOutput.value(dev), dev);
245
        }
246
247
        return qlReturn;
248
}
249
250
void JackAudioOutputRegistrar::setDeviceChoice(const QVariant &choice, Settings &s) {
251
        Q_UNUSED(choice);
252
        Q_UNUSED(s);
253
}
254
255
JackAudioInput::JackAudioInput() {
256
        bRunning = true;
257
        iMicChannels = 0;
258
};
259
260
JackAudioInput::~JackAudioInput() {
261
        bRunning = false;
262
        iMicChannels = 0;
263
        qmMutex.lock();
264
        qwcWait.wakeAll();
265
        qmMutex.unlock();
266
        wait();
267
}
268
269
void JackAudioInput::run() {
270
        if (jasys && jasys->bJackIsGood) {
271
            iMicFreq = jasys->iSampleRate;
272
            iMicChannels = 1;
273
            eMicFormat = SampleFloat;
274
            initializeMixer();
275
        }
276
277
        qmMutex.lock();
278
        while (bRunning)
279
                qwcWait.wait(&qmMutex);
280
        qmMutex.unlock();
281
}
282
283
JackAudioOutput::JackAudioOutput() {
284
        bRunning = true;
285
        iChannels = 0;
286
}
287
288
JackAudioOutput::~JackAudioOutput() {
289
        bRunning = false;
290
        iChannels = 0;
291
        qmMutex.lock();
292
        qwcWait.wakeAll();
293
        qmMutex.unlock();
294
        wait();
295
}
296
297
void JackAudioOutput::run() {
298
        if (jasys && jasys->bJackIsGood) {
299
            unsigned int chanmasks[32];
300
301
            chanmasks[0] = SPEAKER_FRONT_LEFT;
302
            chanmasks[1] = SPEAKER_FRONT_RIGHT;
303
304
            eSampleFormat = SampleFloat;
305
            iMixerFreq = jasys->iSampleRate;
306
            iChannels = 1;
307
            initializeMixer(chanmasks);
308
        }
309
310
        qmMutex.lock();
311
        while (bRunning)
312
                qwcWait.wait(&qmMutex);
313
        qmMutex.unlock();
314
}
(-)mumble-1.2.2.orig/src/mumble/JackAudio.h (+98 lines)
Line 0 Link Here
1
/* Copyright (C) 2011, Benjamin Jemlich <pcgod@users.sourceforge.net>
2
   Copyright (C) 2011, Filipe Coelho <falktx@gmail.com>
3
4
   All rights reserved.
5
6
   Redistribution and use in source and binary forms, with or without
7
   modification, are permitted provided that the following conditions
8
   are met:
9
10
   - Redistributions of source code must retain the above copyright notice,
11
     this list of conditions and the following disclaimer.
12
   - Redistributions in binary form must reproduce the above copyright notice,
13
     this list of conditions and the following disclaimer in the documentation
14
     and/or other materials provided with the distribution.
15
   - Neither the name of the Mumble Developers nor the names of its
16
     contributors may be used to endorse or promote products derived from this
17
     software without specific prior written permission.
18
19
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
#ifndef _JACKAUDIO_H
33
#define _JACKAUDIO_H
34
35
#include "AudioInput.h"
36
#include "AudioOutput.h"
37
#include <jack/jack.h>
38
#include <QWaitCondition>
39
40
class JackAudioOutput;
41
class JackAudioInput;
42
43
class JackAudioSystem : public QObject {
44
        private:
45
                Q_OBJECT
46
                Q_DISABLE_COPY(JackAudioSystem)
47
        protected:
48
                jack_client_t* client;
49
                jack_port_t* in_port;
50
                jack_port_t* out_port;
51
52
                static int process_callback(jack_nframes_t nframes, void *arg);
53
                static int srate_callback(jack_nframes_t frames, void *arg);
54
                static void shutdown_callback(void *arg);
55
        public:
56
                QHash<QString, QString> qhInput;
57
                QHash<QString, QString> qhOutput;
58
                bool bJackIsGood;
59
                int iSampleRate;
60
                QMutex qmWait;
61
                QWaitCondition qwcWait;
62
63
                void init_jack();
64
                void close_jack();
65
66
                JackAudioSystem();
67
                ~JackAudioSystem();
68
};
69
70
class JackAudioInput : public AudioInput {
71
                friend class JackAudioSystem;
72
        private:
73
                Q_OBJECT
74
                Q_DISABLE_COPY(JackAudioInput)
75
        protected:
76
                QMutex qmMutex;
77
                QWaitCondition qwcWait;
78
        public:
79
                JackAudioInput();
80
                ~JackAudioInput();
81
                void run();
82
};
83
84
class JackAudioOutput : public AudioOutput {
85
                friend class JackAudioSystem;
86
        private:
87
                Q_OBJECT
88
                Q_DISABLE_COPY(JackAudioOutput)
89
        protected:
90
                QMutex qmMutex;
91
                QWaitCondition qwcWait;
92
        public:
93
                JackAudioOutput();
94
                ~JackAudioOutput();
95
                void run();
96
};
97
98
#endif
(-)mumble-1.2.2.orig/src/mumble/mumble.pro (+13 lines)
Lines 93-103 Link Here
93
unix {
93
unix {
94
  HAVE_PULSEAUDIO=$$system(pkg-config --modversion --silence-errors libpulse)
94
  HAVE_PULSEAUDIO=$$system(pkg-config --modversion --silence-errors libpulse)
95
  HAVE_PORTAUDIO=$$system(pkg-config --modversion --silence-errors portaudio-2.0)
95
  HAVE_PORTAUDIO=$$system(pkg-config --modversion --silence-errors portaudio-2.0)
96
  HAVE_JACKAUDIO=$$system(pkg-config --modversion --silence-errors jack)
96
97
97
  !isEmpty(HAVE_PORTAUDIO):!CONFIG(no-portaudio) {
98
  !isEmpty(HAVE_PORTAUDIO):!CONFIG(no-portaudio) {
98
    CONFIG *= portaudio
99
    CONFIG *= portaudio
99
  }
100
  }
100
101
102
  !isEmpty(HAVE_JACKAUDIO):!CONFIG(no-jackaudio) {
103
    CONFIG -= portaudio
104
    CONFIG *= jackaudio
105
  }
106
101
  !isEmpty(HAVE_PULSEAUDIO):!CONFIG(no-pulseaudio) {
107
  !isEmpty(HAVE_PULSEAUDIO):!CONFIG(no-pulseaudio) {
102
    CONFIG -= portaudio
108
    CONFIG -= portaudio
103
    CONFIG *= pulseaudio
109
    CONFIG *= pulseaudio
Lines 110-115 Link Here
110
    QMAKE_CXXFLAGS_DEBUG *= -I../../speex/include -I../../speexbuild
116
    QMAKE_CXXFLAGS_DEBUG *= -I../../speex/include -I../../speexbuild
111
  }
117
  }
112
118
119
  jackaudio {
120
        DEFINES *= USE_JACKAUDIO
121
        PKGCONFIG *= jack
122
        HEADERS *= JackAudio.h
123
        SOURCES *= JackAudio.cpp
124
  }
125
113
  CONFIG *= link_pkgconfig
126
  CONFIG *= link_pkgconfig
114
127
115
  PKGCONFIG *= openssl sndfile
128
  PKGCONFIG *= openssl sndfile

Return to bug 380161