2 * Copyright (C) 2011-2012 Juho Vähä-Herttua
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
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 GNU
12 * Lesser General Public License for more details.
15 #include "raopservice.h"
21 audio_init(void *cls
, int bits
, int channels
, int samplerate
)
24 QMetaObject::invokeMethod((QObject
*)cls
, "audioInit", Qt::BlockingQueuedConnection
,
25 Q_ARG(void*, (void*)&session
),
28 Q_ARG(int, samplerate
));
33 audio_set_volume(void *cls
, void *session
, float volume
)
35 QMetaObject::invokeMethod((QObject
*)cls
, "audioSetVolume", Qt::BlockingQueuedConnection
,
36 Q_ARG(void*, session
),
37 Q_ARG(float, volume
));
41 audio_process(void *cls
, void *session
, const void *buffer
, int buflen
)
43 QMetaObject::invokeMethod((QObject
*)cls
, "audioProcess", Qt::BlockingQueuedConnection
,
44 Q_ARG(void*, session
),
45 Q_ARG(void*, (void*)buffer
),
50 audio_flush(void *cls
, void *session
)
52 QMetaObject::invokeMethod((QObject
*)cls
, "audioFlush", Qt::BlockingQueuedConnection
,
53 Q_ARG(void*, session
));
57 audio_destroy(void *cls
, void *session
)
59 QMetaObject::invokeMethod((QObject
*)cls
, "audioDestroy", Qt::BlockingQueuedConnection
,
60 Q_ARG(void*, session
));
63 RaopService::RaopService(QObject
*parent
) :
68 /* This whole hack is required because QAudioOutput
69 * needs to be created in a QThread, threads created
70 * outside Qt are not allowed (they have no eventloop) */
71 m_handler
.moveToThread(&m_thread
);
74 RaopService::~RaopService()
78 dnssd_destroy(m_dnssd
);
82 bool RaopService::init()
84 raop_callbacks_t raop_cbs
;
87 raop_cbs
.cls
= &m_handler
;
88 raop_cbs
.audio_init
= audio_init
;
89 raop_cbs
.audio_set_volume
= audio_set_volume
;
90 raop_cbs
.audio_process
= audio_process
;
91 raop_cbs
.audio_flush
= audio_flush
;
92 raop_cbs
.audio_destroy
= audio_destroy
;
94 QFile
file("airport.key");
96 // This is used when running from Qt Creator on Mac
97 file
.setFileName("../../../../airport.key");
100 // This is used when running from Qt Creator on Windows
101 file
.setFileName("../airport.key");
103 if (!file
.exists()) {
106 file
.open(QIODevice::ReadOnly
);
107 QByteArray array
= file
.read(file
.size());
110 m_raop
= raop_init(&raop_cbs
, array
.data());
115 m_dnssd
= dnssd_init(&error
);
117 raop_destroy(m_raop
);
125 bool RaopService::start(const QString
& name
, quint16 port
)
127 const char hwaddr
[] = { 0x48, 0x5d, 0x60, 0x7c, 0xee, 0x22 };
129 if (!m_raop
|| !m_dnssd
|| m_thread
.isRunning()) {
134 if (raop_start(m_raop
, &port
, hwaddr
, sizeof(hwaddr
), NULL
) < 0) {
139 if (dnssd_register_raop(m_dnssd
, name
.toUtf8(), port
, hwaddr
, sizeof(hwaddr
), 0) < 0) {
149 void RaopService::stop()
152 dnssd_unregister_raop(m_dnssd
);
157 if (m_thread
.isRunning()) {