I have an application (SDR type) where the software generates a nice stream of PCM audiosamples and the output is made audible using QAudio to the soundcard of the PC
The current version runs with Qt5, and I am in the transition from Qt5 to Qt
I have a version that runs fine under Linux, but - it is cross compiled - under Windows it does not generate sound and does not give error messages either
It should be possible to have it run under Windows, the audioOutput example from the Qt sourcetree runs both under Linux and Windows fine
The structure of the class, driving the output, is basic, it is a class in which an AudioSink and a IODevice are created and the incoming samples are stored in a large ringbuffer
Part of the code that is executed on a (re)start, where newDeviceIndex is just in index is the vector ith device descriptions. the format is stored in m_settings:
if (newDeviceIndex < 0)
return;
QAudioDevice currentDevice
= outputDevices. at (newDeviceIndex);
fprintf (stderr, "going for %s\n",
currentDevice. description (). toLatin1 (). data ());
m_audioSink = new QAudioSink (currentDevice, m_settings);
m_audioSink -> setBufferSize (8 * 32768);
connect (m_audioSink, &QAudioSink::stateChanged,
this, &Qt_Audio::state_changed);
//
// and run off
theIODevice -> close ();
delete theIODevice;
theIODevice = new Qt_AudioDevice (mr, &tempBuffer);
theIODevice -> start ();
m_audioSink -> start (theIODevice);
QtAudio::Error err = m_audioSink -> error ();
fprintf (stderr, "Errorcode %d\n", (int)(err));
if (newDeviceIndex < 0)
return;
QAudioDevice currentDevice
= outputDevices. at (newDeviceIndex);
fprintf (stderr, "going for %s\n",
currentDevice. description (). toLatin1 (). data ());
m_audioSink = new QAudioSink (currentDevice, m_settings);
m_audioSink -> setBufferSize (8 * 32768);
connect (m_audioSink, &QAudioSink::stateChanged,
this, &Qt_Audio::state_changed);
//
// and run off
theIODevice -> close ();
delete theIODevice;
theIODevice = new Qt_AudioDevice (mr, &tempBuffer);
theIODevice -> start ();
m_audioSink -> start (theIODevice);
QtAudio::Error err = m_audioSink -> error ();
fprintf (stderr, "Errorcode %d\n", (int)(err));
To copy to clipboard, switch view to plain text mode
And the IODevice is the most simple one one can imagine
void Qt_AudioDevice::start () {
if (running. load ())
return;
fprintf (stderr, "Opening QIODevice %s\n", b ? "ok" : "error");
running. store (true);
}
// we always return "maxSize" bytes
qint64 Qt_AudioDevice::readData (char* buffer, qint64 maxSize) {
qint64 amount = 0;
// "maxSize" is the requested size in bytes
// "amount" is in uint8_t's
amount = Buffer -> getDataFromBuffer (buffer, maxSize);
if (amount < maxSize) {
for (int i = amount; i < maxSize; i ++)
buffer [i] = (char)(0);
}
totalBytes_l += amount;
missedBytes_l += maxSize - amount;
return maxSize;
}
void Qt_AudioDevice::start () {
if (running. load ())
return;
bool b = open (QIODevice::ReadOnly);
fprintf (stderr, "Opening QIODevice %s\n", b ? "ok" : "error");
running. store (true);
}
// we always return "maxSize" bytes
qint64 Qt_AudioDevice::readData (char* buffer, qint64 maxSize) {
qint64 amount = 0;
// "maxSize" is the requested size in bytes
// "amount" is in uint8_t's
amount = Buffer -> getDataFromBuffer (buffer, maxSize);
if (amount < maxSize) {
for (int i = amount; i < maxSize; i ++)
buffer [i] = (char)(0);
}
totalBytes_l += amount;
missedBytes_l += maxSize - amount;
return maxSize;
}
To copy to clipboard, switch view to plain text mode
On a state change I print the state,
On Linux, the message is - after opening the device "activeState"
On windows, the message with opening is that opening was successfull and the state is "Idle"
Format is 48000, 2 channels and floats (bit I tried Int16 as well with the same result)
Any help would really be appreciated
Jan
Bookmarks