I'm writing a cross-platform Qt-based program that from time to time needs to play back audio supplied externally (outside my control) as raw PCM. The exact format is 16 bit little-endian PCM at various common sample rates.
My first obvious idea was to use Qt's own Phonon for audio playback, but there are two problems with this approach:
As far as I can see, Phonon does not support headerless PCM data. I would have to hack around this and fake a WAV header every time playback starts. Not a showstopper, though.
More importantly: There doesn't seem to be any way to control how Phonon (and its backends such as xine, PulseAudio, DirectX, whatever) prebuffers. Its default behaviour seems to be something like 5 seconds of prebuffering, which is way too much for me. I'd prefer about 1 second, and I'd definitely like to be able to control this!
I'm currently looking at Gstreamer, FFMPEG and libvlc. Any thoughts? Since my audio is in a very simple format and I don't need to do fancy mixing stuff (just volume control), I'd like a simple, free (as in freedom), cross-platform and widely available library.
Qt 4.6 has the new QtMultimedia module.
https://doc.qt.io/archives/4.6/qtmultimedia.html
The QAudioOutput class would seem to do what you want - it just plays raw PCM data.
ffmpeg, libvlc and gstreamer have abilities beyond raw pcm, such as codec support.
For your purposes, SDL (example 1, example 2), OpenAL, QAudioOutput are sufficient. SDL is probably the most popular option.
Also, why do you want to control buffering? Buffering a lot means less interrupts and lower power consumption.
Have you looked at OpenAL?
Related
I have a question about playing .wav files in C++. I search for a method to play it on Linux and Windows and I want to break up it while a function has been ended, did you know a sample for this?
Thanks for any Answer :)!
I am from Germany, please don't be angry about my grammar or spelling :D.
There are several ways to do this.
The simplest, ugliest and most hackish way to do this is to write directly to your sound device located in /dev/snd/. However this really depends on your linux distribution and some modern ones no longer allows you to do this. In general, direct read / write to /dev/ devices is fading away. Here is a question answering this.
For a very long time, the "official" way was to use alsa library which uses a C style interface. It is usually pretty tricky, full of pitfalls and "workarounds" that depends on your exact audio hardware.
I think that alsa is getting gradually replaced by jack, which I hope is easier to use. I don't have any experience with this one.
The last method I know is with portaudio, which as the name implies, is somewhat portable between at least windows, linux and osx.
All of these library will allow you to control your audio hardware, init / setup / play. What is simple about wav files is that the content is raw pcm, which is usually the format used by those libraries. The wav format is usually like this :
[wav header] [audio data until the end of the file]
If you can manage a few milliseconds of garbage when you start playing, you can "safely" send the header for playback as well and avoid parsing it. You will have to understand PCM formats however and should bring some additional readings.
As an added "trick" which doesn't directly concern C++, I strongly suggest using Audacity. It is a small program which I see like the notepad / vim of audio files. It is small, it loads fast, allows you to copy / paste segments of audio and detect pcm formats. (Actually, you just change pcm settings until the audio "sounds" right, but still useful)
The title mentioned Linux, but then you mentioned Windows and Linux in the post.
For Linux, best is to use gstreamer if you insist on C++. Look through the gstreamer code for gst-launch. It is run as below in a Linux machine.
$ gst-launch filesrc location="location of file" ! wavparse ! alsasink
From, http://sanchayanmaity.github.io/beagleboard-xm/linux/programming/software/2014/08/07/playing-wavmp3-file-using-gstreamer-in-code.html
For windows, or if you want to use OS agnostic code on both Windows and Linux, you can use SDL,
http://lazyfoo.net/SDL_tutorials/lesson11/
Another alternative (cross-platform, Object oriented), is SFML. Check the audio wav file playback example at,
http://www.sfml-dev.org/tutorials/2.0/audio-sounds.php
I have an SDL app, that works under Linux, Mac and Windows. It's something like a media player, and can play audio just fine. I'd like to add audio recording feature to it, but I'd like to encode it in real time to MP3. Can anyone point me to an example how can I use LibLame, LibSoX, or possibly some other library to achieve this?
-- OR --
I'm also willing to rewrite the whole thing into something easier to manage than C++. I've looked at Kivy and Love2d which uses Lua, but audio recording it's still an issue there. If you know ANY toolkit that:
is cross platform
helps you build GUI using your own graphics
can play AND record mp3 files
ideally can operate under framebuffer (no X Window server under Linux)
Please let me know. I'm looking at Python + Pygame + Pyaudio, it can do graphics and output sound, but still can't record MP3's, only WAV's. Any way to integrate LAME into this to make it work?
FMOD can play practically anything, and handle audio input as well, although I don't know if integrating an entire audio engine is a bit overkill for your project.
It's free for non-commercial usage.
As for encoding, LAME is definitely the de-facto choice for MP3.
There's a very simple library called lame_enc.dll which wraps LAME's capabilities in a simple API. It's Windows only, but you could look at it's source for a good reference on how to use LAME.
I'm looking for a C++ library (for Linux, but preferably cross-platform) that will easily let me read audio files in some trivial format such as a raw byte stream, generate audio data in the same trivial format, and write audio files. I don't care what format the reading and writing happens in, as long as it's free (beer and speech) and commonly supported. I'm going to be reading, transforming, and generating many small audio clips in a very parallel program, so I need the library to be fast and thread-safe.
Additional features I'd like, but do not require, are simple DSP functions (FFT, filters), and recording/playback through the sound card.
A bit of Googling didn't turn anything up, but perhaps I'm using the wrong search terms. I've almost exclusively found libraries for use in apps that record or playback, and it's unclear if they have the ability to generate sound from raw bytes, and even if they do they seem like overkill for my purpose. I've been considering just writing my own library to manipulate WAV files, since they seem simple enough, but I'd rather not reinvent the wheel if I can avoid it.
I may be completely off here, but from your description it sounds like you are looking for something like OpenAL or FMOD. OpenAL is completely free, but FMOD is free for non-commercial use only. Both are thread-safe and are cross-platform.
As you can guess, getting started with OpenAL is much harder than FMOD due to lack of (good) documentation and proper examples.
File R/W: http://www.mega-nerd.com/libsndfile/
FFT: http://www.fftw.org/
Hardware Interfacing: http://jackaudio.org/
GStreamer is cross-platform and widely used:
GStreamer is a library for constructing graphs of media-handling components. The applications it supports range from simple Ogg/Vorbis playback, audio/video streaming to complex audio (mixing) and video (non-linear editing) processing.
I would recommend trying STK:
https://ccrma.stanford.edu/software/stk/
You can just copy-past things you need into your program(lets say reading and writing .wav files). It is fairly simple to use. It has tutorials(with C++ code). They say it is cross-platform. If you are going to compile it for Linux just remember to add '-D__LITTLE_ENDIAN__' to your g++ command line.
P.S. Just take a look at first tutorials. They are really short, simple and straightforward.
How about SDL and SDL_Mixer? No DSP functionality though.
Take a look at the BASS library www.un4seen.com
BASS is free for non-commercial use.
Platforms: Win32, OSX, Linux
BASS is also available for the Win64, WinCE, iOS, Android, and ARM Linux platforms.
BASS is an audio library for use in software on several platforms. Its
purpose is to provide developers with powerful and efficient sample,
stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via
OS codecs and add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3
music (MP3/OGG compressed MODs), and recording functions. All in a
compact DLL/LIB that won't bloat your distribution.
BASS supports lots of addons, easy to use, flexible, good documentation/examples and the best support I have ever seen.
As you like it has:
Custom generated samples
And also WAV/AIFF/MP3/MP2/MP1/OGG
Example: Create a 440hz sine wave sample.
HSAMPLE sample=BASS_SampleCreate(256, 28160, 1, 1,
BASS_SAMPLE_LOOP|BASS_SAMPLE_OVER_POS); // create sample
short data[128]; // data buffer
int a;
for (a=0; a<128; a++)
data[a]=(short)(32767.0*sin((double)a*6.283185/64)); // sine wave
BASS_SampleSetData(sample, data); // set the sample's data
Playback through the sound card
Simultaneously use multiple soundcards, and move channels between them
Custom DSP
Apply any effects that you want, in any order you want
DSP is set up using:
HDSP BASS_ChannelSetDSP(
DWORD handle,
DSPPROC *proc,
void *user,
int priority
);
Example: A simple DSP function to swap the left/right channels of a stereo 16-bit channel.
void CALLBACK SwapDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
short *s=buffer;
for (; length; length-=4, s+=2) {
short temp=s[0];
s[0]=s[1];
s[1]=temp;
}
}
Recording
Flexible recording system, with multiple device support and input selection, (WMA encoding & broadcasting via the add-on, and other formats via BASSenc)
FFT
Example: Perform a 1024 sample FFT on a channel and list the result.
float fft[512]; // fft data buffer
BASS_ChannelGetData(channel, fft, BASS_DATA_FFT1024);
for (int a=0; a<512; a++)
printf("%d: %f\n", a, fft[a]);
I'm looking for a free, portable C or C++ library which allows me to play mono sound samples on specific channels in a 5.1 setup. For example the sound should be played with the left front speaker whereby all other speakers remain silent. Is there any library capable of doing this?
I had a look at OpenAL. However, I can only specify the position from which the sound should come, but it seems to me that I cannot say something like "use only the front left channel to play this sound".
Any hints are welcome!
I had a look at OpenAL. However, I can only specify the position from which the sound should come, but it seems to me that I cannot say something like "use only the front left channel to play this sound".
I don't think this is quite true. I think you can do it with OpenAL, although it's not trivial. OpenAL only does the positional stuff if you feed it mono format data. If you give it stereo or higher, it plays the data the way it was provided. However, you're only guaranteed stereo support. You'll need to check to see if the 5.1 channel format extension is available on your system (AL_FORMAT_51CHN16). If so, then, I think that you feed your sound to the channel you want and feed zeroes to all the others channels when you buffer the samples. Note that you need hardware support for this on the sound card. A "generic software" device won't cut it.
See this discussion from the OpenAL mailing list.
Alternatively, I think that PortAudio is Open, cross-platform, and supports multiple channel output. You do still have to interleave the data so that if you're sending a sound to a single channel, you have to send zeroes to all the others. You'll also still need to do some checking when opening a stream on a device to make sure the device supports 6 channels of output.
A long time ago I used RTAudio. But I cannot say if this lib can do what you want to archive, but maybe it helps.
http://fmod.org could do the trick too
I use the BASS Audio Library http://www.un4seen.com for all my audio, sound and music projects. I am very happy with it.
BASS is an audio library to provide developers with powerful and efficient sample, stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3 music (MP3/OGG compressed MODs), and recording functions. All in a tiny DLL, under 100KB* in size. C/C++, Delphi, Visual Basic, MASM, .Net and other APIs are available. BASS is available for the Windows, Mac, Win64, WinCE, Linux, and iOS platforms.
I have never used it to play different samples in a 5.1 configuration. But, according their own documentation, it should be possible.
Main features
Samples Support for WAV/AIFF/MP3/MP2/MP1/OGG and custom generated samples
Sample streams Stream any sample data in 8/16/32 bit, with both "push" and "pull" systems. File streams MP3/MP2/MP1/OGG/WAV/AIFF file streaming. Internet file streaming. Stream data from HTTP and FTP servers (inc. Shoutcast, Icecast & Icecast2), with IDN and proxy server support and adjustable buffering. ** Custom file streaming ** Stream data from anywhere using any delivery method, with both "push" and "pull" systems
Multi-channel Support for more than plain stereo, including multi-channel OGG/WAV/AIFF files
...
Multiple outputs Simultaneously use multiple soundcards, and move channels between them
Speaker assignment Assign streams and MOD musics to specific speakers to take advantage of hardware capable of more than plain stereo (up to 4 separate stereo outputs with a 7.1 soundcard)
3D sound Play samples/streams/musics in any 3D position
Licensing
BASS is free for non-commercial use. If you are a non-commercial entity (eg. an individual) and you are not making any money from your product (through sales, advertising, etc), then you can use BASS in it for free. Otherwise, one of the following licences will be required.
I was wondering, what was a good cross-platform utility for doing audio recording/ playback/ seeking in C++? I was thinking going the route of ALUT (OpenAL), but is there a better way? If not, do you guys know of any good tutorials/sample code for ALUT?
SFML and SDL have support for playing many different sound formats and are cross plattform. Neither of them provides you with means for recording audio. Then there is PortAudio which looks pretty active but I do have no experience with it at all.
Qt actually has some audio functions since version 4.6.
Didn't try the input for myself, but if you scroll down a bit in the Qt-Documentation
there is a basic example.
For Input you can work a layer higher with Qt. Here is an example.