Repeatedly playing contents of QByteArray through QAudioOutput
-
Emits a beep in Audacity as one would expect (if pasted 1000 times).
-
Ok so the beep would be somewhat like the burb you get with Qt?
Im wondering about
QAudioFormat format;
and
new QAudioOutput(format, this);
If it will copy it. ( I assume yes) (+ wav file works)
so dont matter it goes out of scope.also
else{ // restart from scratch
QDataStream s(buf, QIODevice::ReadWrite);
audio->start(s.device());
}
That seems to be a new / another QDataStream and not the one you made a class member? -
Since then I've changed the code to use the member stream:
else{ // restart from scratch audio->start(s->device()); // s is a class member here }
No, the 'burp' is a short burst, a short abrupt chirp, nothing like a proper sine wave.
The audio output clearly thinks it is playing audio, as there are no events until I hit the Stop button and then it printsStopped audio IdleState
into the debug output. It's just that there is no sound coming from the speakers. The program also appears in the Windows mixer once the audio output starts.
-
My best guess is that it dont like the format but
I cannot see why not.
Also
http://stackoverflow.com/questions/32049950/realtime-streaming-with-qaudiooutput-qt
which seems same code, it seems it plays for him.
And you seem to check errors etc so Im out of suggestions for now :( -
I am somewhat suspicious of the repeated starting of the output from the same stream.
Should there be something to re-wind the stream to the beginning? Like this:else{ // restart from scratch s->resetStatus(); audio->start(s->device()); }
which does not actually help, I am just posting this as a question.
That was one of the reasons I wanted to create a local variable for the stream in both places: for initial start and re-start.Or perhaps do I need to create a completely separate stream for reading from the buffer? I am getting impression that the stream is either at the end after writing data into the buffer, or when I want to re-start.
-
Hi
I wondered the same.
Like it plays once and then are at the end.
You could maybe put sample generation in a function and create a new sample
at restart. mostly for test. -
No luck! I tried to add this to the state handler:
else{ // restart from scratch delete buf; delete s; buf = new QByteArray(); s = new QDataStream(buf, QIODevice::ReadWrite); for(float ii=0.0f; ii<360.0f; ii+=(360.0f*1000.0f/af.sampleRate())){ int sample = ((int)(qSin(qDegreesToRadians(ii)) * 32768)); (*s) << sample; // char sample = (char)(qSin(qDegreesToRadians(ii)) * 128); // buf->append(sample); // qDebug() << (int)sample; } audio->start(s->device()); } break;
Still no sound.
Also tried completely removing re-start and simply repeating the wave 1000 times to get 1 second of sound, but to no avail:for(int i=0; i<1000; i++){ for(float ii=0.0f; ii<360.0f; ii+=(360.0f*1000.0f/af.sampleRate())){ int sample = ((int)(qSin(qDegreesToRadians(ii)) * 32768)); (*s) << sample; // char sample = (char)(qSin(qDegreesToRadians(ii)) * 128); // buf->append(sample); qDebug() << (int)sample; } }
It saved a 180,000 byte file which plays a nearly perfect tone when imported into Audacity (as far as I can tell with the cheap speakers).
-
Ok so data is good
but it seems it dont like. I wonder if some of the format settings
is wrong but I really cant spot it.Is it possible for me to have the project to play with ?
-
@mrjj
You can grab it from here: qtcreator project
Thank you for your time! -
Hi,
I'd recommend taking a look at the spectrum example in the example of the QtMultimedia module. There's a small tone generator that should get you started.
-
This is it, that project set me onto the right track:
s->device()->close(); s->device()->open(QIODevice::ReadOnly);
before starting playback fixed the issue! So that really was the stream at the end.
Super, thanks a lot!Development is not over, as I suspect that closing and re-opening the device is time consuming and would cause jerky sound, but at least it is clear now why it was not working.
For now when I try to play the buffer with 1 sine wave repeatedly, using
s->device()->seek(0);
before restarting audio, the speakers are just clicking fast instead of playing a sine wave. This approach may be entirely unsustainable due to overhead involved in restarting both IO device and Audio output. -
Super
I tried with
http://doc.qt.io/qt-5/qbuffer.html#details
but had no luck. -
Overhead of seeking to 0 and re-starting audio must be huge!
When I am playing 1 second of 1000 waves and re-starting, there is about 1/10 second delay between the blocks.
This is on i7-2600 3.4 GHz machine. I will need to change the approach completely, but at least you two got me onto the right track - appreciate your help! -
@nulluse
You are most welcome :)
Its pretty huge delay.
Im surprised seek is that expensive.funny, i have i7-2600 also. Old now but still a fine CPU
-
Note
Adding just
s->device()->seek(0);
made it play for me. -
I was wondering if we subclass
QIODevice and implement
qint64 QIODevice::readData(char * data, qint64 maxSize)
If we then would endless supply data and avoid the
delay as we never restart then.
I have never subclassed QIODevice so not sure what minimum
override is.