QT5 QSound does not play all wave files - qt

I am in the midst of migrating our app based on QT4.X to QT5. Phonon support has been removed in QT5, so I have changed my code that plays a wave file to use QSound.
Change is pretty straightforward. I just had to use QSound, which is now located in Multimedia library. Here is the code:
QSound::play("small_wave_file.wav");
For most of my wave files, this works just fine; however, for my wave file(with 44100Hz sample rate) it does not work.
Official QT bug can be found here.
UPDATE: This bug has been fixed in qt 5.1

It turns out that some wave files confuse QSound. Still not sure exactly what causes the issue. When I loaded my wave file in Audacity, and then exported it back to a different wave file without any changes(same sample rate...). QSound played the file just fine.
In MacOSX when I click "Get Info" on the problematic wave file, general wave info record from the wave file was not available; so perhaps QSound was unable to get sample rate information from; and because it did not know which sample rate to expect from the wave file?
The interesting part is that iTunes played the original file just fine, and it had the correct sample rate somehow. Also Phonon used to play the original file as well just fine.
Anyhow, hopefully this helps with some people that had issues with QSound::play() method.
UPDATE: Since QSound::play() was very buggy on the mac, I opted to use the native NSSound to play my wave files from QT application on the mac. Here is the code:
void play_sound( const char* file)
{
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:[NSString stringWithUTF8String:file] byReference:NO];
[sound play];
[sound release];
}

Also note that Qt has several different sound playback APIs. For small file playback with lower latency I found this to be much faster:
http://doc.qt.io/qt-5/qsoundeffect.html#details
Also:
http://doc.qt.io/qt-5/qmediaplayer.html

Related

KDE Taskbar Progress

I am trying to show a progress in the taskbar of the plasma desktop using the KDE Frameworks. In short, it want to do the same thing as dolphin, when it copies files:
I'm kinda stuck, because I don't even know where to get started. The only thing I found that could be useful is KStatusBarJobTracker, but I don't know how to use it. I could not find any tutorials or examples how to do this.
So, after digging around, and thanks to the help of #leinir, I was able to find out the following:
Since Plasma 5.6 KDE supports the Unitiy DBus Launcher-API, which can be used, for example, to show progress
I found a post on AskUbuntu that explains how to use the API with Qt
The real problem is: This only works, if you have a valid desktop file in one of the standard locations! You need to pass the file as parameter of the DBus message to make it work.
Based on this information, I figured out how to use it and created a GitHub repository, that supports cross platform taskbar progress, and uses this API for the linux implementation.
However, here is how to do it anyways. It should work for KDE Plasma and the Unity desktop, maybe more (haven't tried any others):
Create a .desktop file for your application. For test purpose, this can be a "dummy" file, that could look like this:
[Desktop Entry]
Type=Application
Version=1.1
Name=MyApp
Exec=<path_to>/MyApp
Copy that file to ~/.local/share/applications/ (or wherever user specific desktop files go on your system)
In your code, all you need to do is execute the following code, to update the taskbar state:
auto message = QDBusMessage::createSignal(QStringLiteral("/com/example/MyApp"),
QStringLiteral("com.canonical.Unity.LauncherEntry"),
QStringLiteral("Update"));
//you don't always have to specify all parameters, just the ones you want to update
QVariantMap properties;
properties.insert(QStringLiteral("progress-visible"), true);// enable the progress
properties.insert(QStringLiteral("progress"), 0.5);// set the progress value (from 0.0 to 1.0)
properties.insert(QStringLiteral("count-visible"), true);// display the "counter badge"
properties.insert(QStringLiteral("count"), 42);// set the counter value
message << QStringLiteral("application://myapp.desktop") //assuming you named the desktop file "myapp.desktop"
<< properties;
QDBusConnection::sessionBus().send(message);
Compile and run your application. You don't have to start it via the desktop file, at least I did not need to. If you want to be sure your application is "connected" to that desktop file, just set a custom icon for the file. Your application should show that icon in the taskbar.
And thats basically it. Note: The system remembers the last state when restarting the application. Thus, you should reset all those parameters once when starting the application.
Right, so as it turns out you are right, there is not currently a tutorial for this. This reviewboard request, however, shows how it was implemented in KDevelop, and it should be possible for you to work it out through that :) https://git.reviewboard.kde.org/r/127050/
ps: that there is no tutorial now might be a nice way for you to hop in and help out, by writing a small, self contained tutorial for it... something i'm sure would be very much welcomed :)

Generating a waveform from an audio (or video) file?

I'm trying to understand how I can generate a waveform from an audio (or video) file to display to the user.
I've been googling around for quite a while now and can't determine if this is even possible in Qt without using something like FFmpeg. I've seen all of these classes: QMediaPlayer, QMediaContent, QMediaResource, QAudioProbe and experimented with the Qt Media Player Example but am just not seeing where I can access the actual audio buffer.
So I have 2 questions:
Is what I want to do even possible without 3rd party libraries?
If it is possible, can some kind soul outline what I need to read and understand in order to access the audio data
I have tried the suggestions from this question (Audio visualization with QMediaPlayer) but the result of audioProbe->setSource(player) is always false and the method processBuffer never gets called.
audioProbe = new QAudioProbe(this);
bool success = audioProbe->setSource(player);
qDebug() << success;
connect(audioProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
Update: Adding some additional detail in the hope of clarifying things.
For testing/learning I am using the Media Player Example which ships with Qt, so it is set up correctly with Q_OBJECT etc.
For audio, I tested with both .mp3 and .wav files. FWIW, the player example won't play video for some reason (.mp4, .avi were tested)
The player in the code is QMediaPlayer – which inherits from QMediaObject. The example code for the Player class is here. I added my code (in original comment above) right after the player is instantiated. I also tried adding it once media is loaded.
I tried declaring my slot first as private, then as public – either way, it is never called.
Frustrating that such a simple thing is so hard.
Going the "no external library" route will likely just lead to more of a headache and more work than is necessary. The other advantage of going with an established library is you won't be bound to one file format, as not all formats store their data the same way. If the audio format is uncompressed (wav or other) you can read the header until you get to the data chunk. An answer to this question here details this in C. You should be able to get an idea for the file format from this to apply it to another language.
You will want to understand how many channels are in the wav file, bit depth, and also the sampling rate before you can do anything worthwhile with the data. All this info can be grabbed from the header.
It turns out that QAudioProbe is not supported on OSX – the platform I am working on. Took quite a while (a "Qt while. . .") to ferret that info out so I am posting it here explicitly.
See this document for full details: Qt 5.5.0 Multimedia Backends

Android QR code reading libs

I have an Android QR code reading app that runs on a cheap phone with no autofocus. QR code that I must read is small and on camera preview looks blurry. The one app able to read this code is NeoReader.
Does everybody know good free libraries to read QR codes?
I know that:
ZBar (it's ok but not works with blurry code)
ZXing (this Barcode reader not reads the required code; don't tried to integrate)
NeoReader SDK (not free)
My init code for ZBar:
scanner = new ImageScanner();
scanner.setConfig(0, Config.ENABLE, 0);
scanner.setConfig(Symbol.QRCODE, Config.ENABLE, 1);
scanner.setConfig(0, Config.X_DENSITY, 1);
scanner.setConfig(0, Config.Y_DENSITY, 1);
If none of the four above is an option (or even if they where!) I would strongly suggest using Googles own library found in Google Play services under the namespace com.google.android.gms.vision.barcode. It scans the codes locally, fast and robust, and you have full control of the source code in just a few classes.
For a simple example check out Android QR Code Reader Made Easy. That should get you up and running in no time! There's also further reading linked at the end of the post for advanced examples.

Saving recording to MP3 container in Qt

I am programming on the Windows 7 platform using Qt 4.8.4, Qt Mobility 1.2 and C++. I am attempting to record audio from the front jack and save it to a file in mp3 format. I have the program working with the LAME encoder, but the file is being saved as WAV.
It appears that I have no control over the container type, which is defaulting to PCM/WAV.
Here are the QAudioEncoderSettings I am using:
QAudioEncoderSettings settings;
settings.setCodec("audio/mpeg");
settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
settings.setBitRate(boxValue(ui->bitrateBox).toInt());
settings.setQuality(QtMultimediaKit::EncodingQuality(ui->qualitySlider->value()));
settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
QtMultimediaKit::ConstantQualityEncoding :
QtMultimediaKit::ConstantBitRateEncoding);
QString container = "audio/x-mp3";
capture->setEncodingSettings(settings, QVideoEncoderSettings(), container);
A post recording conversion is not an option, as the files may become quite large, and the probability that the process would be ended before the conversion was complete is quite high.
Thank you for any help provided.
You can try Qt Media Encoding Library for that - http://qt-project.org/forums/viewthread/29117/

Delay before playing embedded mp3 in Actionscript / Flex 3

I am embedding an mp3 into my Flex project for use as a sound effect, but I am finding that every time I play it, there is a delay of about half a second from when I call .play() to when you can hear the sound. This makes it weird because I want the sound effects to sync to game events. My mp3 itself is only about a fifth of a second long so it isn't because of the contents of the mp3.
I'm embedding with
[Embed(source="assets/Tock.mp3")]
[Bindable]
public static var TockSound:Class;
public var tock_sound:SoundAsset;
and then playing with
if (tock_sound == null) {
tock_sound = new TockSound() as SoundAsset;
}
Alert.show("tock");
tock_sound.play();
I know there's a delay because the sound plays about a half second after the Alert displays. I did consider that maybe it was the initial loading time of constructing the TockSound, but the delay is there on all the subsequent calls as well.
How can I avoid this delay on playing a sound?
Update: It turns out this delay is only present when playing the swf on Linux. I believe it is a Linux-specific flaw in Adobe's flash player.
Not sure about the reason, other than Flash always has had some bad audio latency issues. Read Tinic's blog to stay on top of this stuff: http://www.kaourantin.net/
One thing that might help: make sure your MP3 is 44.1kHz or else Flash will need to resample it.
You can actually embed a WAV file, it just takes work. You embed it as a byte array, and in FP9, dynamically construct a SWF file on the fly. Pretty horrible, but doable. :-) In FP10, you can use the dynamic sound API, so it's easy.
Try StandingWave
http://code.google.com/p/standingwave/
It has the ability to "cache" the sound before playing getting rid of those delays and clicks you normally hear
I haven't worked with audio in Flash too much but it sounds like the half second delay might be the Flash Player opening up the file and reading it into memory. You could try doing a play() and a stop() when you load the application. That might push it into memory.
The other option is using the StandingWave library which was built by the guys at Noteflight. You can get some additional control over the audio files with that library and hopefully it'll help your delay problem.
The problem is that all MP3s have a random amount of blank time at the beginning of the file that is put there during the compression process. Modern software jukeboxes(itunes, songbird etc...) compensate for this by scanning the file before its played and determining the songs actual starting point. Your best bet for sound effects is to use .wav files as their format allows for instant playback, but with a filesize hit.
you might also try: http://www.mptrim.com/ <- they claim to be able to trim the space off the mp3.

Resources