src/platform/qt/AudioDevice.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "AudioDevice.h"
7
8#include "LogController.h"
9
10#include "core/thread.h"
11#include "gba/audio.h"
12
13using namespace QGBA;
14
15AudioDevice::AudioDevice(QObject* parent)
16 : QIODevice(parent)
17 , m_context(nullptr)
18{
19 setOpenMode(ReadOnly);
20}
21
22void AudioDevice::setFormat(const QAudioFormat& format) {
23 if (!m_context || !mCoreThreadIsActive(m_context)) {
24 LOG(QT, INFO) << tr("Can't set format of context-less audio device");
25 return;
26 }
27 double fauxClock = GBAAudioCalculateRatio(1, m_context->sync.fpsTarget, 1);
28 mCoreSyncLockAudio(&m_context->sync);
29 blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0),
30 m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock);
31 blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1),
32 m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock);
33 mCoreSyncUnlockAudio(&m_context->sync);
34}
35
36void AudioDevice::setInput(mCoreThread* input) {
37 m_context = input;
38}
39
40qint64 AudioDevice::readData(char* data, qint64 maxSize) {
41 if (maxSize > 0xFFFFFFFFLL) {
42 maxSize = 0xFFFFFFFFLL;
43 }
44
45 if (!m_context->core) {
46 LOG(QT, WARN) << tr("Audio device is missing its core");
47 return 0;
48 }
49
50 mCoreSyncLockAudio(&m_context->sync);
51 int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0));
52 if (available > maxSize / sizeof(GBAStereoSample)) {
53 available = maxSize / sizeof(GBAStereoSample);
54 }
55 blip_read_samples(m_context->core->getAudioChannel(m_context->core, 0), &reinterpret_cast<GBAStereoSample*>(data)->left, available, true);
56 blip_read_samples(m_context->core->getAudioChannel(m_context->core, 1), &reinterpret_cast<GBAStereoSample*>(data)->right, available, true);
57 mCoreSyncConsumeAudio(&m_context->sync);
58 return available * sizeof(GBAStereoSample);
59}
60
61qint64 AudioDevice::writeData(const char*, qint64) {
62 LOG(QT, WARN) << tr("Writing data to read-only audio device");
63 return 0;
64}