formats.h file containing WAV file format info - c

I am trying to make a prog which can record voice and store it in digital audio format on LINUX using ALSA. (currently using Ubuntu).
While looking for some help on net, I found this code from here
#include "formats.h"
...
...
WaveChunkHeader wch, ch = {WAV_FMT,16};
WaveHeader h;
WaveFmtBody f;
wch.type = WAV_DATA;
...
...
However, I don't have "formats.h" header file on my system. Any one know from where(which dev pkg) I can get this header file (containing audio file format related info)?
Thanks,
Vikram

it should be in the alsa-utils package, subdirectory aplay:
http://alsa-utils.sourcearchive.com/documentation/1.0.17/formats_8h-source.html

Related

libsox: record from default microphone

I need to open the default audio capture device and start recording. libsox seems to be a nice cross-platform solution. Using the binary frontend, I can just rec test.wav and the default microphone is activated.
However, when browsing the documentation, no similar functionality exists. This thread discusses precisely the same topic as my question, but doesn't seem to have reached a solution.
Where could an example of using libsox for recording from the default audio device be located?
You can record using libsox. Just set the input file to "default" and set the filetype to the audio driver (e.g. coreaudio on mac, alsa or oss on linux)
const char* audio_driver = "alsa";
sox_format_t* input = sox_open_read("default", NULL, NULL, audio_driver);
Look at some examples for more info on how to structure the rest of the code.
You need to record with alsa first and use libsox for the right format. libsox is not for recording. see example: https://gist.github.com/albanpeignier/104902

Sound eXchange (Sox) transformation of files, individually and in batches

I am new to programming (just a little bit of python), and I am trying to run a tutotrial that first needs files in wav format. My directory has a bunch of .au files that I am trying to transform to .wav :
tony#VirtualBox:/media/sf_Dropbox/data/genres/classical$ ls
classical.00001.au classical.00018.au classical.00035.au classical.00052.au classical.00069.au classical.00086.au
classical.00002.au classical.00019.au classical.00036.au classical.00053.au classical.00070.au classical.00087.au
classical.00003.au classical.00020.au classical.00037.au classical.00054.au classical.00071.au classical.00088.au
classical.00004.au classical.00021.au classical.00038.au classical.00055.au classical.00072.au classical.00089.au
classical.00005.au classical.00022.au classical.00039.au classical.00056.au classical.00073.au classical.00090.au
classical.00006.au classical.00023.au classical.00040.au classical.00057.au classical.00074.au classical.00091.au
classical.00007.au classical.00024.au classical.00041.au classical.00058.au classical.00075.au classical.00092.au
classical.00008.au classical.00025.au classical.00042.au classical.00059.au classical.00076.au classical.00093.au
classical.00009.au classical.00026.au classical.00043.au classical.00060.au classical.00077.au classical.00094.au
classical.00010.au classical.00027.au classical.00044.au classical.00061.au classical.00078.au classical.00095.au
classical.00011.au classical.00028.au classical.00045.au classical.00062.au classical.00079.au classical.00096.au
classical.00012.au classical.00029.au classical.00046.au classical.00063.au classical.00080.au classical.00097.au
classical.00013.au classical.00030.au classical.00047.au classical.00064.au classical.00081.au classical.00098.au
classical.00014.au classical.00031.au classical.00048.au classical.00065.au classical.00082.au classical.00099.au
classical.00015.au classical.00032.au classical.00049.au classical.00066.au classical.00083.au classical.au
classical.00016.au classical.00033.au classical.00050.au classical.00067.au classical.00084.au classical.wav
classical.00017.au classical.00034.au classical.00051.au classical.00068.au classical.00085.au
But when running the sox command, I get this:
tony#VirtualBox:/media/sf_Dropbox/data/genres/classical$ sox classical.0000.au classical.0000.wav
sox FAIL formats: can't open input file `classical.0000.au': No such file or directory
Does anybody know what's happening? Also, how can I run sox for a whole batch instead of one by one?
Without looking up the documentation for sox, it looks like 'sox classical.00001.au classical.00001.wav' might work. From the ls output, there is no file called classical.0000.au in that directory, but there is one called classical.00001.au.

ALSA Api: How to play two wave files simultaneously?

What is the required API configuration/call for playing two independent wavefiles overlapped ?
I tried to do so , I am getting resource busy error. Some pointers to solve the problem will be very helpful.
Following is the error message from snd_pcm_prepare() of the second wavefile
"Device or resource busy"
You can configure ALSA's dmix plugin to allow multiple applications to share input/output devices.
An example configuration to do this is below:
pcm.dmixed {
type dmix
ipc_key 1024
ipc_key_add_uid 0
slave.pcm "hw:0,0"
}
pcm.dsnooped {
type dsnoop
ipc_key 1025
slave.pcm "hw:0,0"
}
pcm.duplex {
type asym
playback.pcm "dmixed"
capture.pcm "dsnooped"
}
# Instruct ALSA to use pcm.duplex as the default device
pcm.!default {
type plug
slave.pcm "duplex"
}
ctl.!default {
type hw
card 0
}
This does the following:
creates a new device using the dmix plugin, which allows multiple apps to share the output stream
creates another using dsnoop which does the same thing for the input stream
merges these into a new duplex device that will support input and output using the asym plugin
tell ALSA to use the new duplex device as the default device
tell ALSA to use hw:0 to control the default device (alsamixer and so on)
Stick this in either ~/.asoundrc or /etc/asound.conf and you should be good to go.
For more information see http://www.alsa-project.org/main/index.php/Asoundrc#Software_mixing.
ALSA does not provide a mixer. If you need to play multiple audio streams at the same time, you need to mix them together on your own.
The easiest way this can be accomplished is by decoding the WAV files to float samples, add them, and clip them when converting them back to integer samples.
Alternatively, you can try to open the default audio device (and not a hardware device like "hw:0") multiple times, once for each stream you wish to play, and hope that the dmix ALSA plugin is loaded and will provide the mixing functionality.
As ALSA provides a mixer device by default (dmix), you can simply use aplay, like so :
aplay song1.wav &
aplay -Dplug:dmix song2.wav
If your audio files are the same rate and format, then you don't need to use plug. It becomes :
aplay song1.wav &
aplay -Ddmix song2.wav
If however you want to program this method, there are some C++ audio programming tutorials here. These tutorials show you how to load audio files and operate different audio subsystems, such as jackd and ALSA.
In this example it demonstrates playback of one audio file using ALSA. It can be modified by opening a second audio file like so :
Sox<short int> sox2;
res=sox2.openRead(argv[2]);
if (res<0 && res!=SOX_READ_MAXSCALE_ERROR)
return SoxDebug().evaluateError(res);
Then modify the while loop like so :
Eigen::Array<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> buffer, buffer2;
size_t totalWritten=0;
while (sox.read(buffer, pSize)>=0 && sox2.read(buffer2, pSize)>=0){
if (buffer.rows()==0 || buffer.rows()==0) // end of the file.
break;
// as the original files were opened as short int, summing will not overload the int buffer.
buffer+=buffer2; // sum the two waveforms together
playBack<<buffer; // play the audio data
totalWritten+=buffer.rows();
}
You can use this configuration also
pcm.dmix_stream
{
type dmix
ipc_key 321456
ipc_key_add_uid true
slave.pcm "hw:0,0"
}
pcm.mix_stream
{
type plug
slave.pcm dmix_stream
}
Update it in ~/.asoundrc or /etc/asound.conf
You can use command
For wav file
aplay -D mix_stream "filename"
For raw or pcmfile
aplay -D mix_stream -c "channels" -r "rate" -f "format" "filename"
Enter the value for channels, rate, format and filename as per your audio file
following is a very simplified multi-thread playback solution (assuming both files are the same sample format, same channel number and same frequency):
starting buffer based thread per each file decoding (have to make this code 2 times - for file1 and for file2):
import wave
import threading
periodsize = 160
f = wave.open(file1Wave, 'rb')
file1Alive = True
file1Thread = threading.Thread(target=_playFile1)
file1Thread.daemon = True
file1Thread.start()
file decoding thread itself (also has to be defined twice - for file1 and for file2) :
def _playFile1():
# Read data from RIFF
while file1Alive:
if file1dataReady:
time.sleep(.001)
else:
data1 = f.readframes(periodsize)
if not data1:
file1Alive = False
f.close()
else:
file1dataReady == True
starting merging thread (aka funnel) to merge file decodings
import alsaaudio
import threading
sink = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, device="hw:CARD=default")
sinkformat = 2
funnelalive = True
funnelThread = threading.Thread(target=self._funnelLoop)
funnelThread.daemon = True
funnelThread.start()
merge and play (aka funnel) thread
def _funnelLoop():
# Reading all Inputs
while funnelalive:
# if nothing to play - time to selfdestruct
if not file1Alive and not file2Alive:
funnelalive = False
sink.close()
else:
if file1dataReady and file2dataReady:
# merging data from others but first
datamerged = audioop.add(data2, data2, sinkformat)
file1dataReady = False
file2dataReady = False
sink.write(datamerged)
time.sleep(.001)

How to play .m4s file given in mpd of MPEG-DASH on player?

I have downloaded the MPDs "http://dash.edgesuite.net/adobe/hdworld_dash/HDWorld.mpd" and all related .m4s files.
I tried running it on VLC player. But the format is not recognized by VLC player.
I have downloaded this media segment using wget (1 to 14 segments are available)
http://dash.edgesuite.net/adobe/hdworld_dash/hdworld_seg_hdworld_0696kbps_ffmpeg.mp4.video_temp2.m4s.
Can anybody tell me solution how to run .m4s format file on player?
System: Ubuntu 11.10
You need the initialization segment. It is often named "00" or "init" or doesn't have a sequence number like the other files, and often ends in ".mp4" rather than ".m4s". Then you just concatenate the files together. You can start anywhere in the sequence so long as you begin with the initialization segment.
For example
cat init.mp4 *.m4s > output.mp4
Then you have a playable mp4 file with content, assuming there is no encryption (DRM) applied to it.
.m4s file format is ISO Base Media File. i.e. MPEG-4 Part 14. read specs for more info you may get m4s player for windows. As far as I know on Linux platform GPAC will help. You can create your own MPD from any media source using MP4Box a GPAC tool.
You can use MP4Client for playing your DASHed Media from MPD. Actually .m4s's separate segment is not able to play by its own bcoz player should know Codec and mime type to play any media and m4s is not supported by any player, i.e. it has its own header and data (moof & mdat).
For playing MPD which contains many m4s segment (you can make your own MPD or download each audio and video segment separately from any MPD & put it in to a same folder):
install GPAC.
$MP4Client MYWorld.mpd will open Osmo4 player and you can see your video is playing. Enjoy..
FYI, local streaming server can also play this video:
$MP4Client http://localhost/MYWorld.mpd
if not working change segmentAlignment flag, i.e. <AdaptationSet segmentAlignment="true" subsegmentAlignment="true">.
you can play it using GPAC player, installing it with all the third party codecs also -
http://gpac.wp.mines-telecom.fr/player/
some ppl claim that they are able use vlc, i have not tested it.
Try this in the OSX terminal:
open -a Osmo4 example.mpd
It works for me.

Playing a wav file using pulseaudio APIs?

For example, this is how to use pulseaudio: http://freedesktop.org/software/pulseaudio/doxygen/pacat-simple_8c-example.html
but I'm not clear on how I can simply play a wav file or an ogg file for that matter.
The example code will play raw PCM data from a file. The trick is getting the data from a wav file into this format. The Microsoft wav files look like this:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
Wav files just store raw PCM data. You just have to strip the header off the wav file and dump the rest into a file (extension is irrelevant, but I like to use .raw). That is, you can write a program that either: copies everything past byte 44 into a new file, or just read everything after that directly into a buffer. Pass either format to the pulseaudio example and you should be good to go.
Things to look out for: the endianness of the file and your system; bitdepth; number of channels. These are in the wav header and you may have to read them and tell pa_simple before you play the data. Although, I'm not sure if pa_simple detects this information for you. I like to work with the asynchronous implementation and there I just input the format directly.
-E
linux-commands-examples - pacat
pacat --list-file-formats
aiff AIFF (Apple/SGI)
au AU (Sun/NeXT)
avr AVR (Audio Visual Research)
caf CAF (Apple Core Audio File)
flac FLAC (Free Lossless Audio Codec)
htk HTK (HMM Tool Kit)
iff IFF (Amiga IFF/SVX8/SV16)
mat MAT4 (GNU Octave 2.0 / Matlab 4.2)
mat MAT5 (GNU Octave 2.1 / Matlab 5.0)
mpc MPC (Akai MPC 2k)
oga OGG (OGG Container format)
paf PAF (Ensoniq PARIS)
pvf PVF (Portable Voice Format)
raw RAW (header-less)
rf64 RF64 (RIFF 64)
sd2 SD2 (Sound Designer II)
sds SDS (Midi Sample Dump Standard)
sf SF (Berkeley/IRCAM/CARL)
voc VOC (Creative Labs)
w64 W64 (SoundFoundry WAVE 64)
wav WAV (Microsoft)
wav WAV (NIST Sphere)
wav WAVEX (Microsoft)
wve WVE (Psion Series 3)
xi XI (FastTracker 2)

Resources