android fix

This commit is contained in:
pszsh 2026-01-25 04:27:50 -08:00
parent 2bc03b0143
commit fde087c63d
2 changed files with 49 additions and 35 deletions

4
.sdkmanrc Normal file
View File

@ -0,0 +1,4 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=17-homebrew
gradle=9.2.1

View File

@ -1,3 +1,5 @@
// src/AudioEngine.cpp
#include "AudioEngine.h"
#include <QMediaDevices>
#include <QAudioDevice>
@ -7,6 +9,7 @@
#include <QAudioBuffer>
#include <QDebug>
#include <QtGlobal>
#include <algorithm>
AudioEngine::AudioEngine(QObject* parent) : QObject(parent) {
m_processors.push_back(new Processor(m_frameSize, m_sampleRate));
@ -60,7 +63,6 @@ void AudioEngine::loadTrack(const QString& filePath) {
} else {
delete m_fileSource;
m_fileSource = nullptr;
// Fix: Handle content:// URIs correctly
if (filePath.startsWith("content://")) {
m_decoder->setSource(QUrl(filePath));
} else {
@ -83,38 +85,18 @@ void AudioEngine::onBufferReady() {
QAudioBuffer buffer = m_decoder->read();
if (!buffer.isValid()) return;
// Fix: Explicit cast to int to avoid warning
const int frames = static_cast<int>(buffer.frameCount());
const int channels = buffer.format().channelCount();
auto sampleType = buffer.format().sampleFormat();
// We store everything as Stereo Int16 to ensure compatibility with all sinks
if (sampleType == QAudioFormat::Int16) {
const int16_t* src = buffer.constData<int16_t>();
if (!src) return;
for (int i = 0; i < frames; ++i) {
float left = 0.0f;
float right = 0.0f;
if (channels == 1) {
left = src[i] / 32768.0f;
right = left;
} else if (channels >= 2) {
left = src[i * channels] / 32768.0f;
right = src[i * channels + 1] / 32768.0f;
}
m_pcmData.append(reinterpret_cast<const char*>(&left), sizeof(float));
m_pcmData.append(reinterpret_cast<const char*>(&right), sizeof(float));
}
}
else if (sampleType == QAudioFormat::Float) {
const float* src = buffer.constData<float>();
if (!src) return;
for (int i = 0; i < frames; ++i) {
float left = 0.0f;
float right = 0.0f;
int16_t left = 0;
int16_t right = 0;
if (channels == 1) {
left = src[i];
@ -124,8 +106,35 @@ void AudioEngine::onBufferReady() {
right = src[i * channels + 1];
}
m_pcmData.append(reinterpret_cast<const char*>(&left), sizeof(float));
m_pcmData.append(reinterpret_cast<const char*>(&right), sizeof(float));
m_pcmData.append(reinterpret_cast<const char*>(&left), sizeof(int16_t));
m_pcmData.append(reinterpret_cast<const char*>(&right), sizeof(int16_t));
}
}
else if (sampleType == QAudioFormat::Float) {
const float* src = buffer.constData<float>();
if (!src) return;
auto toInt16 = [](float x) -> int16_t {
return static_cast<int16_t>(std::clamp(x, -1.0f, 1.0f) * 32767.0f);
};
for (int i = 0; i < frames; ++i) {
float l = 0.0f;
float r = 0.0f;
if (channels == 1) {
l = src[i];
r = l;
} else if (channels >= 2) {
l = src[i * channels];
r = src[i * channels + 1];
}
int16_t left = toInt16(l);
int16_t right = toInt16(r);
m_pcmData.append(reinterpret_cast<const char*>(&left), sizeof(int16_t));
m_pcmData.append(reinterpret_cast<const char*>(&right), sizeof(int16_t));
}
}
}
@ -155,7 +164,7 @@ void AudioEngine::play() {
QAudioFormat format;
format.setSampleRate(44100);
format.setChannelCount(2);
format.setSampleFormat(QAudioFormat::Float);
format.setSampleFormat(QAudioFormat::Int16); // Universal format
QAudioDevice device = QMediaDevices::defaultAudioOutput();
if (device.isNull()) {
@ -164,13 +173,12 @@ void AudioEngine::play() {
}
if (!device.isFormatSupported(format)) {
qWarning() << "AudioEngine: Float format not supported, using preferred format.";
qWarning() << "AudioEngine: Int16 format not supported, using preferred format.";
format = device.preferredFormat();
}
m_sink = new QAudioSink(device, format, this);
connect(m_sink, &QAudioSink::stateChanged, this, [this](QAudio::State state){
if (state == QAudio::IdleState && m_sink->error() == QAudio::NoError) {
if (m_buffer.bytesAvailable() == 0) {
@ -201,7 +209,8 @@ void AudioEngine::stop() {
void AudioEngine::seek(float position) {
if (m_pcmData.isEmpty()) return;
qint64 pos = position * m_pcmData.size();
pos -= pos % 8;
// Align to 4 bytes (2 channels * 2 bytes per sample)
pos -= pos % 4;
if (m_buffer.isOpen()) m_buffer.seek(pos);
}
@ -217,16 +226,17 @@ void AudioEngine::onProcessTimer() {
qint64 currentPos = m_buffer.pos();
emit positionChanged((float)currentPos / m_pcmData.size());
const float* samples = reinterpret_cast<const float*>(m_pcmData.constData());
qint64 sampleIdx = currentPos / sizeof(float);
qint64 totalSamples = m_pcmData.size() / sizeof(float);
// Convert Int16 back to Float for DSP
const int16_t* samples = reinterpret_cast<const int16_t*>(m_pcmData.constData());
qint64 sampleIdx = currentPos / sizeof(int16_t);
qint64 totalSamples = m_pcmData.size() / sizeof(int16_t);
if (sampleIdx + m_frameSize * 2 >= totalSamples) return;
std::vector<float> ch0(m_frameSize), ch1(m_frameSize);
for (int i = 0; i < m_frameSize; ++i) {
ch0[i] = samples[sampleIdx + i*2];
ch1[i] = samples[sampleIdx + i*2 + 1];
ch0[i] = samples[sampleIdx + i*2] / 32768.0f;
ch1[i] = samples[sampleIdx + i*2 + 1] / 32768.0f;
}
m_processors[0]->pushData(ch0);