New package: mumble122 - for JACK support patch

This commit is contained in:
davehome 2011-11-01 23:36:29 +00:00
parent 72d47e2535
commit 06509dd5d7
2 changed files with 551 additions and 0 deletions

View file

@ -0,0 +1,454 @@
diff -U 3 -H -d -r -N -- mumble-1.2.2.orig/src/mumble/JackAudio.cpp mumble-1.2.2/src/mumble/JackAudio.cpp
--- src/mumble/JackAudio.cpp 1970-01-01 01:00:00.000000000 +0100
+++ src/mumble/JackAudio.cpp 2011-01-26 06:02:00.000000000 +0000
@@ -0,0 +1,314 @@
+/* Copyright (C) 2011, Benjamin Jemlich <pcgod@users.sourceforge.net>
+ Copyright (C) 2011, Filipe Coelho <falktx@gmail.com>
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Neither the name of the Mumble Developers nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "JackAudio.h"
+#include "User.h"
+#include "Global.h"
+#include "MainWindow.h"
+#include "Timer.h"
+
+#include <cstring>
+
+static JackAudioSystem *jasys = NULL;
+
+class JackAudioInputRegistrar : public AudioInputRegistrar {
+ public:
+ JackAudioInputRegistrar();
+ virtual AudioInput *create();
+ virtual const QList<audioDevice> getDeviceChoices();
+ virtual void setDeviceChoice(const QVariant &, Settings &);
+ virtual bool canEcho(const QString &) const;
+};
+
+class JackAudioOutputRegistrar : public AudioOutputRegistrar {
+ public:
+ JackAudioOutputRegistrar();
+ virtual AudioOutput *create();
+ virtual const QList<audioDevice> getDeviceChoices();
+ virtual void setDeviceChoice(const QVariant &, Settings &);
+};
+
+class JackAudioInit : public DeferInit {
+ public:
+ JackAudioInputRegistrar *airJackAudio;
+ JackAudioOutputRegistrar *aorJackAudio;
+ void initialize() {
+ jasys = new JackAudioSystem();
+ jasys->init_jack();
+ jasys->qmWait.lock();
+ jasys->qwcWait.wait(&jasys->qmWait, 1000);
+ jasys->qmWait.unlock();
+ if (jasys->bJackIsGood) {
+ airJackAudio = new JackAudioInputRegistrar();
+ aorJackAudio = new JackAudioOutputRegistrar();
+ } else {
+ airJackAudio = NULL;
+ aorJackAudio = NULL;
+ delete jasys;
+ jasys = NULL;
+ }
+ };
+ void destroy() {
+ if (airJackAudio)
+ delete airJackAudio;
+ if (aorJackAudio)
+ delete aorJackAudio;
+ if (jasys) {
+ jasys->close_jack();
+ delete jasys;
+ jasys = NULL;
+ }
+ };
+};
+
+static JackAudioInit jackinit; //unused
+
+JackAudioSystem::JackAudioSystem() {
+ bJackIsGood = false;
+ iSampleRate = 0;
+}
+
+JackAudioSystem::~JackAudioSystem() {
+}
+
+void JackAudioSystem::init_jack()
+{
+ client = jack_client_open("mumble", JackNullOption, 0);
+
+ if (client) {
+ in_port = jack_port_register(client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
+ out_port = jack_port_register(client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ jack_set_process_callback(client, process_callback, this);
+ jack_set_sample_rate_callback(client, srate_callback, this);
+ jack_on_shutdown(client, shutdown_callback, this);
+
+ iSampleRate = jack_get_sample_rate(client);
+
+ if (jack_activate(client) || in_port == NULL || out_port == NULL) {
+ client = NULL;
+ return;
+ }
+
+ int port_flags;
+ unsigned i = -1;
+ const char** ports = jack_get_ports(client, 0, 0, JackPortIsPhysical);
+
+ if (ports) {
+ while (ports[++i])
+ {
+ jack_port_t* port = jack_port_by_name(client, ports[i]);
+ port_flags = jack_port_flags(port);
+
+ if (port_flags & (JackPortIsPhysical|JackPortIsOutput) && strstr(jack_port_type(port), "audio")) {
+ jack_connect(client, ports[i], jack_port_name(in_port));
+ }
+ if (port_flags & (JackPortIsPhysical|JackPortIsInput) && strstr(jack_port_type(port), "audio")) {
+ jack_connect(client, jack_port_name(out_port), ports[i]);
+ }
+ }
+ }
+
+ jack_free(ports);
+
+ // If we made it this far, then everything is okay
+ qhInput.insert(QString(), tr("Hardware Ports"));
+ qhOutput.insert(QString(), tr("Hardware Ports"));
+ bJackIsGood = true;
+
+ } else {
+ bJackIsGood = false;
+ client = NULL;
+ }
+}
+
+void JackAudioSystem::close_jack()
+{
+ if (client) {
+ jack_deactivate(client);
+ jack_client_close(client);
+ client = NULL;
+ }
+}
+
+int JackAudioSystem::process_callback(jack_nframes_t nframes, void *arg)
+{
+ JackAudioSystem *jas = (JackAudioSystem*)arg;
+
+ if (jas && jas->bJackIsGood) {
+ AudioInputPtr ai = g.ai;
+ AudioOutputPtr ao = g.ao;
+ JackAudioInput *jai = (JackAudioInput*)(ai.get());
+ JackAudioOutput *jao = (JackAudioOutput*)(ao.get());
+
+ if (jai && jai->bRunning && jai->iMicChannels > 0 && !jai->isFinished()) {
+ void* input = jack_port_get_buffer(jas->in_port, nframes);
+ if ((float*)input != 0)
+ jai->addMic(input, nframes);
+ }
+
+ if (jao && jao->bRunning && jao->iChannels > 0 && !jao->isFinished()) {
+ jack_default_audio_sample_t* output = (jack_default_audio_sample_t*)jack_port_get_buffer(jas->out_port, nframes);
+ memset(output, 0, sizeof(jack_default_audio_sample_t)*nframes); //TEST
+ jao->mix(output, nframes);
+ }
+ }
+
+ return 0;
+}
+
+int JackAudioSystem::srate_callback(jack_nframes_t frames, void *arg)
+{
+ JackAudioSystem *jas = (JackAudioSystem*)arg;
+ jas->iSampleRate = frames;
+ return 0;
+}
+
+void JackAudioSystem::shutdown_callback(void *arg)
+{
+ JackAudioSystem *jas = (JackAudioSystem*)arg;
+ jas->bJackIsGood = false;
+}
+
+JackAudioInputRegistrar::JackAudioInputRegistrar() : AudioInputRegistrar(QLatin1String("JACK"), 10) {
+}
+
+AudioInput *JackAudioInputRegistrar::create() {
+ return new JackAudioInput();
+}
+
+const QList<audioDevice> JackAudioInputRegistrar::getDeviceChoices() {
+ QList<audioDevice> qlReturn;
+
+ QStringList qlInputDevs = jasys->qhInput.keys();
+ qSort(qlInputDevs);
+
+ foreach(const QString &dev, qlInputDevs) {
+ qlReturn << audioDevice(jasys->qhInput.value(dev), dev);
+ }
+
+ return qlReturn;
+}
+
+void JackAudioInputRegistrar::setDeviceChoice(const QVariant &choice, Settings &s) {
+ Q_UNUSED(choice);
+ Q_UNUSED(s);
+}
+
+bool JackAudioInputRegistrar::canEcho(const QString &osys) const {
+ Q_UNUSED(osys);
+ return false;
+}
+
+JackAudioOutputRegistrar::JackAudioOutputRegistrar() : AudioOutputRegistrar(QLatin1String("JACK"), 10) {
+}
+
+AudioOutput *JackAudioOutputRegistrar::create() {
+ return new JackAudioOutput();
+}
+
+const QList<audioDevice> JackAudioOutputRegistrar::getDeviceChoices() {
+ QList<audioDevice> qlReturn;
+
+ QStringList qlOutputDevs = jasys->qhOutput.keys();
+ qSort(qlOutputDevs);
+
+ foreach(const QString &dev, qlOutputDevs) {
+ qlReturn << audioDevice(jasys->qhOutput.value(dev), dev);
+ }
+
+ return qlReturn;
+}
+
+void JackAudioOutputRegistrar::setDeviceChoice(const QVariant &choice, Settings &s) {
+ Q_UNUSED(choice);
+ Q_UNUSED(s);
+}
+
+JackAudioInput::JackAudioInput() {
+ bRunning = true;
+ iMicChannels = 0;
+};
+
+JackAudioInput::~JackAudioInput() {
+ bRunning = false;
+ iMicChannels = 0;
+ qmMutex.lock();
+ qwcWait.wakeAll();
+ qmMutex.unlock();
+ wait();
+}
+
+void JackAudioInput::run() {
+ if (jasys && jasys->bJackIsGood) {
+ iMicFreq = jasys->iSampleRate;
+ iMicChannels = 1;
+ eMicFormat = SampleFloat;
+ initializeMixer();
+ }
+
+ qmMutex.lock();
+ while (bRunning)
+ qwcWait.wait(&qmMutex);
+ qmMutex.unlock();
+}
+
+JackAudioOutput::JackAudioOutput() {
+ bRunning = true;
+ iChannels = 0;
+}
+
+JackAudioOutput::~JackAudioOutput() {
+ bRunning = false;
+ iChannels = 0;
+ qmMutex.lock();
+ qwcWait.wakeAll();
+ qmMutex.unlock();
+ wait();
+}
+
+void JackAudioOutput::run() {
+ if (jasys && jasys->bJackIsGood) {
+ unsigned int chanmasks[32];
+
+ chanmasks[0] = SPEAKER_FRONT_LEFT;
+ chanmasks[1] = SPEAKER_FRONT_RIGHT;
+
+ eSampleFormat = SampleFloat;
+ iMixerFreq = jasys->iSampleRate;
+ iChannels = 1;
+ initializeMixer(chanmasks);
+ }
+
+ qmMutex.lock();
+ while (bRunning)
+ qwcWait.wait(&qmMutex);
+ qmMutex.unlock();
+}
diff -U 3 -H -d -r -N -- mumble-1.2.2.orig/src/mumble/JackAudio.h mumble-1.2.2/src/mumble/JackAudio.h
--- src/mumble/JackAudio.h 1970-01-01 01:00:00.000000000 +0100
+++ src/mumble/JackAudio.h 2011-01-26 06:03:58.000000000 +0000
@@ -0,0 +1,97 @@
+/* Copyright (C) 2011, Benjamin Jemlich <pcgod@users.sourceforge.net>
+ Copyright (C) 2011, Filipe Coelho <falktx@gmail.com>
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Neither the name of the Mumble Developers nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _JACKAUDIO_H
+#define _JACKAUDIO_H
+
+#include "AudioInput.h"
+#include "AudioOutput.h"
+#include <jack/jack.h>
+
+class JackAudioOutput;
+class JackAudioInput;
+
+class JackAudioSystem : public QObject {
+ private:
+ Q_OBJECT
+ Q_DISABLE_COPY(JackAudioSystem)
+ protected:
+ jack_client_t* client;
+ jack_port_t* in_port;
+ jack_port_t* out_port;
+
+ static int process_callback(jack_nframes_t nframes, void *arg);
+ static int srate_callback(jack_nframes_t frames, void *arg);
+ static void shutdown_callback(void *arg);
+ public:
+ QHash<QString, QString> qhInput;
+ QHash<QString, QString> qhOutput;
+ bool bJackIsGood;
+ int iSampleRate;
+ QMutex qmWait;
+ QWaitCondition qwcWait;
+
+ void init_jack();
+ void close_jack();
+
+ JackAudioSystem();
+ ~JackAudioSystem();
+};
+
+class JackAudioInput : public AudioInput {
+ friend class JackAudioSystem;
+ private:
+ Q_OBJECT
+ Q_DISABLE_COPY(JackAudioInput)
+ protected:
+ QMutex qmMutex;
+ QWaitCondition qwcWait;
+ public:
+ JackAudioInput();
+ ~JackAudioInput();
+ void run();
+};
+
+class JackAudioOutput : public AudioOutput {
+ friend class JackAudioSystem;
+ private:
+ Q_OBJECT
+ Q_DISABLE_COPY(JackAudioOutput)
+ protected:
+ QMutex qmMutex;
+ QWaitCondition qwcWait;
+ public:
+ JackAudioOutput();
+ ~JackAudioOutput();
+ void run();
+};
+
+#endif
diff -U 3 -H -d -r -N -- mumble-1.2.2.orig/src/mumble/mumble.pro mumble-1.2.2/src/mumble/mumble.pro
--- src/mumble/mumble.pro 2010-02-09 16:34:51.000000000 +0000
+++ src/mumble/mumble.pro 2011-01-26 01:45:55.000000000 +0000
@@ -93,11 +93,17 @@
unix {
HAVE_PULSEAUDIO=$$system(pkg-config --modversion --silence-errors libpulse)
HAVE_PORTAUDIO=$$system(pkg-config --modversion --silence-errors portaudio-2.0)
+ HAVE_JACKAUDIO=$$system(pkg-config --modversion --silence-errors jack)
!isEmpty(HAVE_PORTAUDIO):!CONFIG(no-portaudio) {
CONFIG *= portaudio
}
+ !isEmpty(HAVE_JACKAUDIO):!CONFIG(no-jackaudio) {
+ CONFIG -= portaudio
+ CONFIG *= jackaudio
+ }
+
!isEmpty(HAVE_PULSEAUDIO):!CONFIG(no-pulseaudio) {
CONFIG -= portaudio
CONFIG *= pulseaudio
@@ -110,6 +116,13 @@
QMAKE_CXXFLAGS_DEBUG *= -I../../speex/include -I../../speexbuild
}
+ jackaudio {
+ DEFINES *= USE_JACKAUDIO
+ PKGCONFIG *= jack
+ HEADERS *= JackAudio.h
+ SOURCES *= JackAudio.cpp
+ }
+
CONFIG *= link_pkgconfig
PKGCONFIG *= openssl sndfile

View file

@ -0,0 +1,97 @@
# Template file for 'mumble122'
__pkgname=mumble
pkgname=${__pkgname}122
version=1.2.2
homepage="http://${__pkgname}.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${__pkgname}/${__pkgname}-${version}.tar.gz"
short_desc="Open source, low-latency, high quality voice chat for gaming"
maintainer="davehome <davehome@redthumb.info.tm>"
license="BSD"
checksum=2c564e3d5b7481129482f2365375a2dc77e134c0c00012073cfdfbeadaa49be8
long_desc="
Mumble is a voice chat application for groups. While it can be used for any
kind of activity, it is primarily intended for gaming. It can be compared to
programs like Ventrilo or TeamSpeak. People tend to simplify things, so when
they talk about Mumble they either talk about Mumble the client application
or about Mumble and Murmur the whole voice chat application suite.
This is the old version of mumble with a patch to enable JACK support from
Filipe Coelho (falkTX) of KXStudio."
disable_parallel_build=yes
replaces="lib${__pkgname}<=1.2.3 ${__pkgname}>=0"
provides="${__pkgname}-999"
gtk_iconcache_dirs="/usr/share/icons/hicolor"
Add_dependency run glibc
Add_dependency run protobuf
Add_dependency run libXi
Add_dependency run qt
Add_dependency run libssl
Add_dependency run libspeex
Add_dependency run libjack
Add_dependency run jack
Add_dependency run libsndfile
Add_dependency run libX11
Add_dependency run alsa-lib
Add_dependency run libpulseaudio
Add_dependency run avahi-compat-libs
Add_dependency run MesaLib
Add_dependency run libstdc++
Add_dependency run libgcc
Add_dependency run libogg
Add_dependency run qt-plugin-sqlite
Add_dependency build protobuf-devel
Add_dependency build libXi-devel
Add_dependency build qt-devel
Add_dependency build openssl-devel
Add_dependency build speex-devel
Add_dependency build jack-devel
Add_dependency build libsndfile-devel
Add_dependency build libX11-devel
Add_dependency build alsa-lib-devel
Add_dependency build pulseaudio-devel
Add_dependency build avahi-compat-libs-devel
Add_dependency build MesaLib-devel
Add_dependency build libstdc++-devel
Add_dependency build libogg-devel
Add_dependency build boost-devel
Add_dependency full desktop-file-utils
Add_dependency full hicolor-icon-theme
wrksrc=${__pkgname}-${version}
do_configure()
{
# Needs bundled celt for some reason
qmake -recursive main.pro \
CONFIG+="no-speechd bundled-celt no-bundled-speex no-g15 \
pulseaudio no-embed-qt-translations no-update\
jackaudio no-server" \
DEFINES+="PLUGIN_PATH=/usr/lib/mumble"
}
do_build()
{
make ${makejobs} release
}
do_install()
{
vmkdir usr/bin
vmkdir usr/lib/mumble
vmkdir usr/share/applications
vmkdir usr/share/man/man1
vmkdir usr/share/icons/hicolor/scalable/apps
cp ${wrksrc}/release/mumble ${DESTDIR}/usr/bin
cp ${wrksrc}/release/mumble11x ${DESTDIR}/usr/bin
cp ${wrksrc}/release/*.so* ${DESTDIR}/usr/lib/mumble
cp ${wrksrc}/release/plugins/* ${DESTDIR}/usr/lib/mumble
cp ${wrksrc}/scripts/mumble.desktop ${DESTDIR}/usr/share/applications
cp ${wrksrc}/man/mumble{,11x}.1 ${DESTDIR}/usr/share/man/man1
cp ${wrksrc}/icons/mumble.svg ${DESTDIR}/usr/share/icons/hicolor/scalable/apps
}