A cross-platform LabVIEW library for audio device playback and capture, and for reading and writing audio files.
What's New? - Features - Installation - Usage - Building - Comparison - License - Acknowledgments
- Raspberry Pi / LINX support!
- See the Installation section to get started.
- Support for reading metadata tags (ID3v2, ID3v1, Vorbis Comments, RIFF INFO)
- Support for reading embedded artwork
- Advanced device configuration options
- Misc. bug fixes
- Support for audio playback and capture, including loopback capture
- Playback and capture using selectable backends (WASAPI, DirectSound, Core Audio, PulseAudio, ALSA, etc)
- Multi-channel audio mixer
- Read MP3, FLAC, Ogg Vorbis, and WAV formats
- Read metadata tags (ID3v2, ID3v1, Vorbis Comments, RIFF INFO) and embedded artwork
- Write WAV format (PCM and IEEE Float, with Sony Wave64 support for large files)
- Unicode path support (UTF-8) and unicode tag support
- Cross-platform (Windows, macOS, Linux, Raspberry Pi / LINX), 32-bit and 64-bit
- Simple to use API
G-Audio is published on vipm.io, and can be installed using VI Package Manager (VIPM). The packages are also available as github releases and can be installed manually using VIPM.
- [macOS and Linux] It's recommended to restart LabVIEW after installing the package via VIPM.
- [macOS 10.14 and newer] LabVIEW will require permission to access recording devices when performing audio capture. Make sure to enable this in the Security & Privacy settings. See instructions here on how to enable this setting.
If you want to include the library directly in your project, download or clone the repo and place the G-Audio folder in your source directory, then add G-Audio.lvlib
to your LabVIEW project.
- [macOS] Before adding the library to the project, extract
g_audio_64.framework.zip
located insrc/LabVIEW/G-Audio/lib/
.
Before beginning, ensure your board has the LINX toolkit installed and SSH is enabled, and G-Audio has been installed on the host computer.
SSH into the LINX target (using PuTTy or similar) and run the commands:
sudo schroot -r -c lv
opkg update
opkg install alsa-lib
exit
Note: This library has been compiled for armv7a processors. Other architectures may need to build the library before it can be used. See the Building section.
SCP / SFTP to the LINX target (using WinSCP or similar) and copy the library file located in <vi.lib>\Dataflow_G\G-Audio\lib\LINX\g_audio_32.so
to the /srv/chroot/labview/usr/lib
folder.
Alternatively, SSH to the LINX target and download the library direct from github:
cd /srv/chroot/labview/usr/lib
wget https://github.com/dataflowg/g-audio/raw/main/src/LabVIEW/G-Audio/lib/LINX/g_audio_32.so
Copy some audio files to your device using SCP or SFTP and place them in /home/pi
or your preferred location. Create a LabVIEW project, add your LINX target, then the examples in the Add-ons >> G-Audio >> Examples >> LINX palette.
If you need to adjust the volume output, SSH into the LINX target and run alsamixer
. Press F6, then select the physical audio device (not Default). Use the up and down arrow keys to adjust the volume, or use numbers 1-9 to set the volume in 10% increments. Press Esc to save and exit the mixer.
See the example VIs in Examples to write, read, playback, and capture audio files.
Unit tests are included and can be run individually, or with the AST Unit Tester.
- [macOS 10.14 and newer] LabVIEW will require permission to access recording devices when performing audio capture. Make sure to enable this in the Security & Privacy settings. See instructions here on how to enable this setting.
The Playback Audio
, Capture Audio
, Audio File Read
, and Audio File Write
VIs are malleable, and accept waveform arrays, waveforms, 2D arrays, and 1D arrays with types U8, I16, I32, SGL, and DBL (20 combinations in total). All audio data is processed in its native format, and then converted to the requested format if necessary. For WAV and FLAC files, any conversions are considered lossy, so check the file format before loading to ensure everything is lossless.
If a malleable VI has broken wire inputs and errors about unsupported types, even though the type is supported, try hold Ctrl and click the run arrow. This will force LabVIEW to recompile the VI, and should hopefully fix those broken wires.
G-Audio supports reading ID3v2 and ID3v1 tags from MP3 files, Vorbis Comments from FLAC and Ogg Vorbis files, and RIFF INFO data from WAV files. All tag data is returned as an array of Field
\ Value
clusters from Read Audio File Tags.vi
. The text encoding of Value
can be specified to support tags containing unicode (note the Field
text is always ASCII). Depending on the tag format, Field
is named based on the tag (in the case of Vorbis Comments and ID3v2 TXXX
fields), or mapped to a commonly named field. The table below shows the mapping between a common Field name and various tags.
Field | Description | ID3v2 | ID3v1 | RIFF INFO |
---|---|---|---|---|
TITLE | The title of the track. | TIT2 , TT2 |
Title | INAM |
ARTIST | The track artist. | TPE1 , TP1 |
Artist | IART |
ALBUM | The album title. | TALB , TAL |
Album | IPRD |
ALBUMARTIST | The album artist. | TPE2 , TP2 |
❌ | ❌ |
GENRE | The track's genre. | TCON , TCO |
Genre ID | IGNR |
DATE | The release date, typically the year. | TYER , TYE |
Year | ICRD |
TRACKNUMBER | The track's number in an album. | TRCK , TRK (nn / NN) |
Comment[29] | ITRK |
TRACKTOTAL | The total number of tracks in an album. | TRCK , TRK (nn / NN) |
❌ | ❌ |
DISCNUMBER | The disc number within an album. | TPOS , TPA (nn / NN) |
❌ | ❌ |
DISCTOTAL | The total number of discs in an album. | TPOS , TPA (nn / NN) |
❌ | ❌ |
BPM | Beats Per Minute of the track. | TBPM , TBP |
❌ | ❌ |
COMMENT | Notes and comments on the track. | COMM , COM |
Comment[0-27] | ICMT |
The field / tag mapping is based on the Tag Mapping article on the hydrogenaudio wiki.
Detailed build instructions can be found in BUILDING.md, and covers development environment configuration, compilation details for each target, and VIPM packaging process.
Under Windows, Microsoft Visual Studio Community 2019 is used to compile and test the DLL called by LabVIEW.
Under macOS, Xcode 11.3.1 is used to compile the shared framework.
Under Linux, run the make.sh
script to compile the shared object library, or manually compile with the command g++ -shared -fPIC -o g_audio_64.so *.cpp -lm -lpthread -ldl -O3
.
Under Raspberry Pi / LINX, run the following commands from SSH:
sudo schroot -r -c lv
opkg update
opkg install packagegroup-core-buildessential
opkg install --force-depends libc6-dev
opkg install --force-depends libgcc-s-dev
opkg install libstdc++-staticdev
opkg install git
opkg install alsa-lib-dev
git clone https://github.com/dataflowg/g-audio
cd g-audio/src/C++
g++ -shared -fPIC -o g_audio_32.so *.cpp -lm -lpthread -ldl -std=c++11 -mfpu=neon -mfloat-abi=softfp -O3
cp g_audio_32.so /usr/lib
exit
Feature | G-Audio | LabVIEW Sound | WaveIO |
---|---|---|---|
Selectable backend | ✔️ | ❌ | ✔️ (WASAPI, WinMM, ASIO) |
Cross-platform | ✔️ | ✔️¹ | ❌ (Windows only) |
Runtime device enumeration | ✔️ | ❌² | ✔️ |
Audio device playback | ✔️ | ✔️ | ✔️ |
Audio device capture | ✔️ | ✔️ | ✔️ |
¹ The backend for Linux is OSS, which was deprecated in Linux kernel version 2.5 in favor of ALSA. OSS support is not included out-of-the-box by any of the Linux distributions supported by LabVIEW 2020.
² LabVIEW Sound only enumerates devices when lvsound2.dll is loaded, and can't detect newly added or removed devices unless the entire library is unloaded and loaded again. See this idea exchange entry for details.
Feature | G-Audio | LabVIEW Sound | LabVIEW Audio DataPlugin |
---|---|---|---|
Read WAV (PCM) | ✔️ | ✔️ | ✔️ |
Read WAV (IEEE Float) | ✔️ | ✔️ | ✔️ |
Read MP3 | ✔️ | ❌ | ✔️ |
Sample Accurate MP3 Length? | ✔️ | - | ❌ |
Read FLAC | ✔️ | ❌ | ❌ |
Read Ogg Vorbis | ✔️ | ❌ | ❌ |
Read WMA | ❌ | ❌ | ✔️ |
Read metadata tags | ✔️ | ❌ | ❌ |
Read embedded artwork | ✔️ | ❌ | ❌ |
Write WAV (PCM) | ✔️ | ✔️ | ✔️ |
Write WAV (IEEE Float) | ✔️ | ✔️¹ | ✔️¹ |
Write WAV (64-bit Float) | ✔️ | ❌ | ❌ |
Write Non-WAV formats | ❌ | ❌ | ❌ |
Large file support (>2GB) | ✔️² | ❌ | ❌ |
Unicode paths | ✔️³ | ❌ | ❌ |
Cross-platform | ✔️ | ✔️⁴ | ❌ (Windows only) |
¹ While LabVIEW Sound and LabVIEW Audio DataPlugin both support writing IEEE Float WAV files, writing the file and then reading it back shows they are not lossless. Both the read and write functions appear to be lossy (a file written by LV Sound and read with G-Audio will not be equal to the original data, as will a file written by G-Audio and read by LV Sound). dr_wav's (and by extension, G-Audio's) IEEE Float WAV write and read functions are lossless.
² 64-bit version of LabVIEW required.
³ The path must be a UTF-8 encoded string (not path type) when passed to the Path input of the audio file functions. LabVIEW's file dialog and path controls don't support unicode, so getting the UTF-8 path into LabVIEW will require additional effort. String controls do support unicode with the UseUnicode=TRUE
flag in labview.ini but are encoded as UTF-16 LE, so will require conversion to UTF-8 before use with G-Audio.
⁴ While LabVIEW Sound is cross-platform, testing under macOS and Linux shows writing 32-bit IEEE Float is unsupported.
The underlying mechanism for playback and capture is a callback made from the backend, where it requests the next block of audio data to be sent to the audio device, or the next available block read from the audio device.
The diagram below shows the audio data flow during playback. The function Playback Audio.vim
and the backend callback run asynchronously. The ring buffer sits between the two, and keeps track of the next block of audio to be read (by the callback) and written (from LabVIEW). It's critical sufficient audio data is written to the ring buffer during playback, and read from the buffer during capture, to ensure there are no audio glitches.
Definitions used when referring to the diagram:
Term | Definition |
---|---|
Sample | Single unit of audio data, typically an I16 or SGL |
Frame | Group of samples equal to number of channels |
Period | 10ms of audio data (sample rate / 100). Typically 441 or 480 frames. |
The period size should be regarded as the minimum buffer size when configuring the audio device. Note that the number of frames requested in the callback routine isn't necessarily fixed, and can be larger than a single period.
This library is built using public domain audio decoders and libraries. As such, this library is also made available in the public domain. See LICENSE for details.
This library uses the following public domain libraries. Massive thanks to these authors.
Library | Author | Public Domain License |
---|---|---|
miniaudio | David Reid | Unlicense / MIT0 |
dr_flac.h | David Reid | Unlicense / MIT0 |
dr_wav.h | David Reid | Unlicense / MIT0 |
minimp3 | lieff | CC0 |
stb_image.h | Sean Barrett | Unlicense / MIT |
stb_vorbis.c | Sean Barrett | Unlicense / MIT |
id3tag.h | Mattias Gustavsson | Unlicense / MIT |
thread.h | Mattias Gustavsson | Unlicense / MIT |
base64 | Manuel Badzong | Unlicense |