Cross platform C++11 library for decoding audio (mp3, wav, ogg, opus, flac, etc)

Overview

Libnyquist

Platform Build Status
Microsoft VS2017 x64 Build status
Clang (OSX) & GCC (Linux) Build Status

Libnyquist is a small C++11 library for reading sampled audio data from disk or memory. It is intended to be used an audio loading frontend for games, audio sequencers, music players, and more.

The library does not include patent or license encumbered formats (such as AAC). For portability, libnyquist does not link against platform-specific APIs like Windows Media Foundation or CoreAudio, and instead bundles the source code of reference decoders as an implementation detail.

Libnyquist is meant to be statically linked, which is not the case with other popular libraries like libsndfile (which is licensed under the LGPL). Furthermore, the library is not concerned with supporting very rare encodings (for instance, A-law PCM or the SND format).

While untested, there are no technical conditions that preclude compilation on other platforms with C++11 support (Android NDK r10e+, Linux, iOS, etc).

Format Support

Regardless of input bit depth, the library produces a channel-interleaved float vector, normalized between [-1.0,+1.0]. At present, the library does not provide comprehensive resampling functionality.

  • Wave (+ IMA-ADPCM encoding)
  • MP3
  • Ogg Vorbis
  • Ogg Opus
  • FLAC
  • WavPack
  • Musepack

Known Issues & Bugs

  • See the Github issue tracker.

License

This library is released under the simplied 2 clause BSD license. All included dependencies have been released under identical or similarly permissive licenses.

Comments
  • modplug decoder: multichannel + midi support

    modplug decoder: multichannel + midi support

    Hey there Dimitri,

    Let me know if you are interested in this PR.

    I've bundled the modplug library into libnyquist.

    Modplug is a PD licensed solution to load multichannel music (mod, s3m, xm, it...) It also can play MIDI files and a wide range of WAVs. MIDI files (and .abc files) require the sound patches located in pat/ folder: these samples are either PD or GPL licensed.

    Most if not all of the work came from @JariKomppa 's Soloud repo, so kudos to him :)

    opened by r-lyeh-archived 11
  • mpc mono crash

    mpc mono crash

    Hey there,

    Just giving a try on the library. Nice work so far!

    It seems to crash here with test_data\ad_hoc\44_16_mono.mpc. Stereo mpc is fine though. Does it work on your machine :tm: ? :)

    opened by r-lyeh-archived 6
  • Add WAV-IMA/ADPCM support

    Add WAV-IMA/ADPCM support

    ADPCM is extremely helpful when streaming hundred of megabytes from disk. mmap()-ing wav files from disk, then decoding adpcm on the fly is one of the cheapest solutions, specially for mobile devices.

    The source (MIT license) for a IMA/ADPCM decoder can be found here: https://github.com/afterwise/aw-ima/

    enhancement 
    opened by r-lyeh-archived 6
  • Very low sound quality

    Very low sound quality

    When converting audio files on Windows, no problems are observed, the quality is good. But for some reason, when working with UNIX system (Android), the sound quality becomes much worse. Here is an example of what happens when converting the "TestBeat_Float32.wv" file to the .ogg format on UNIX.

    TestBeat_Float32.zip

    opened by gtreshchev 5
  • Populate the PUBLIC and PRIVATE interface of libnyquist

    Populate the PUBLIC and PRIVATE interface of libnyquist

    When linking against libnyquist:

    • include its public headers in the PUBLIC interface.
    • include its libraries dependencies in the PRIVATE interface.

    Along the way, update the linkage of the examples, it was made PUBLIC unnecessarily, it is an executable, it won't be linked against another target.

    opened by ArthurSonzogni 4
  • fix compilation with mingw

    fix compilation with mingw

    fixes #50 tested with normal linux+make tested with mingw+make from linux seem to work fine in both cases I didn't test MSVC, because I don't have it, though it would be beneficial to test it maybe

    opened by 4321ba 3
  • On MP3 decoding

    On MP3 decoding

    There's no need to justify for this feature. Also I think in 2k18 the technology has already come to a point where MP3 is available for ordinary mortals. Whatever people say against it.

    So there is libmpg123, and as I see it's LGPLv2, so it can be used commercially and requires dynamic linking. But libnyquist is built as a staticlib. Btw, why exactly libnyquist (and LabSound) only support staticlib build?

    May be we could arrange it the other way around. Currently, your AudioDecoder is very rigid. If it allowed some external tampering, I could simply add my own decoder in the middle of runtime.

    Taking the "external" approach even further, I could send the decoded MP3 data in some intermediate format... For example with ".mp3dec" extension, and there will be the decoded data and metadata in a specified format. But this is the least desired way.

    opened by raub 3
  • How come no in-memory vorbis?

    How come no in-memory vorbis?

    Hello!

    I use LabSound as a backend for Node.js bindings. LabSound uses libnyquist to decode audio. For JS I export WebAudioApi-compliant set of classes.

    Among other things it is very important to do in-memory decoding. Because all JS examples and docs provide separate means of loading and decoding for audio files. Namely XHR for webpages, and I use fs.readFile on Node.js. I'm currently trying to reproduce a simple case with file loading. And I found out that LabSound and specifically libnyquist is incapable of doing ogg in memory.

    void VorbisDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
    {
        throw LoadBufferNotImplEx();
    }
    

    But there is, so to speak, a wae. I'll try to fit it into the VorbisDecoder. If I succeed, I'll do a PR.

    Any thoughts on this? libnyquist doesn't seem to be developed too actively these days, are you still going to continue maintaining it?

    opened by raub 3
  • AudioDevice imposes RtAudio dependency

    AudioDevice imposes RtAudio dependency

    I was pointing someone at libnyquist, but they objected due to needing to link WMF or CoreAudio. I think that comes from the AudioDevice dependency on RtAudio?

    I think AudioDevice should be reserved for the examples and tests, but not be in the library itself, as it isn't used anywhere else in the codecs?

    opened by meshula 3
  • Improved example; amalgamated libraries

    Improved example; amalgamated libraries

    Also, for reference, this is the batch file I am using to compile from the command-line:

    cl /Zi /Oy- /MDd /DDEBUG /EHsc ^
            -I include ^
            -I include\libnyquist ^
            -I third_party ^
            -I third_party\flac\src\include ^
            -I third_party\libogg\include ^
            -I third_party\libvorbis\include ^
            -I third_party\musepack\include ^
            -I third_party\opus\celt ^
            -I third_party\opus\silk ^
            -I third_party\opus\silk\float ^
            -I third_party\opus\libopus\include ^
            -I third_party\opus\opusfile\include ^
            -I third_party\opus\opusfile\src\include ^
            -I third_party\wavpack\include ^
            src\*.c* ^
            third_party\rtaudio\RtAudio.cpp /D__WINDOWS_DS__ ole32.lib user32.lib ^
            examples\src\main.cpp
    
    opened by r-lyeh-archived 3
  • Add Musepack support

    Add Musepack support

    Hey there,

    Nice lib you have in here :) Please consider musepack decoding as it is very cheap to decode for mobile devices. Also, license is bsd-3.

    Original source download at: https://www.musepack.net/index.php?pg=src (see sv8 download, libmpcdec/ subfolder)

    Totally optional, I hacked a mpc decoder if you need some guidance (which I doubt :) https://github.com/r-lyeh/wave/blob/master/wave.cpp#L17

    enhancement 
    opened by r-lyeh-archived 3
  • Why are alsa/pulseaudio/jack needed on linux ?

    Why are alsa/pulseaudio/jack needed on linux ?

    Hi, I was curious about it, isn't this library only meant to help load and read audio files ? in this case why are they needed since from what I know these libraries are meant to handle interfacing with the OS on linux to output sound or get input from microphones etc

    atm i could compile my program without specifying one of them but i still get the error on cmake FATAL,On Linux, one of LIBNYQUIST_JACK, LIBNYQUIST_PULSE, or LIBNYQUIST_ASOUND must be set.

    opened by SeleDreams 1
  • Create CMake config file on install

    Create CMake config file on install

    This is a draft to add a CMake config file to allow the library to be found using find_package in config mode.

    A necessary part of this is adding a version number, discussed in #61.

    I used the version 0.1.0 but this can be replaced with whatever version you want to use.

    opened by SamVanheer 0
  • Segmentation fault in FlacDecoderInternal::s_writeCallback when nqr::NyquistIO::Load a bad .flac file

    Segmentation fault in FlacDecoderInternal::s_writeCallback when nqr::NyquistIO::Load a bad .flac file

    Hi,

    I am running some experiments for AFLAPI and it has found a segmentation fault in FlacDecoderInternal::s_writeCallback when nqr::NyquistIO::Load a bad .flac file. This bug may allows attackers to cause DoS, so I report it here.

    Environment: Ubuntu 20.04 + g++ 9.6.0

    Test target: https://github.com/ddiakopoulos/libnyquist/blob/master/examples/src/Main.cpp

    Poc: segv1.zip

    To reproduce:

    1. Complie the hole project with ASAN
    2. Complie the example with ASAN:
    [email protected]:~/test/libnyquist/build/CMakeFiles/libnyquist-examples.dir/examples/src$ g++ -fsanitize=address -o example Main.cpp.o AudioDevice.cpp.o -llibnyquist -lrtaudio
    
    1. Run:
    $ ./example ./segv1.flac
    

    ASAN says:

    [email protected]:~/test/libnyquist/build/CMakeFiles/libnyquist-examples.dir/examples/src$ ./example segv1.flac 
    [rtaudio] Found: 3 device(s)
    	Device: 0 - hw:Ensoniq AudioPCI,0
    	Device: 1 - hw:Ensoniq AudioPCI,1
    	Device: 2 - default
    
    AddressSanitizer:DEADLYSIGNAL
    =================================================================
    ==1646422==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x7efc7260ec30 bp 0x7ffd0d1b4a80 sp 0x7ffd0d1b41e8 T0)
    ==1646422==The signal is caused by a READ memory access.
    ==1646422==Hint: address points to the zero page.
        #0 0x7efc7260ec2f  (/lib/x86_64-linux-gnu/libc.so.6+0xbbc2f)
        #1 0x7efc72b4a37e in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790
        #2 0x563605538c2d in FlacDecoderInternal::s_writeCallback(FLAC__StreamDecoder const*, FLAC__Frame const*, int const* const*, void*) /home/ubuntu/test/libnyquist/src/FlacDecoder.cpp:164
        #3 0x5636055ac8ae in write_audio_frame_to_client_ /home/ubuntu/test/libnyquist/third_party/FLAC/src/stream_decoder.c:2972
        #4 0x56360559e1ac in read_frame_ /home/ubuntu/test/libnyquist/third_party/FLAC/src/stream_decoder.c:2146
        #5 0x56360558cf7b in FLAC__stream_decoder_process_until_end_of_stream /home/ubuntu/test/libnyquist/third_party/FLAC/src/stream_decoder.c:1101
        #6 0x5636055373b3 in FlacDecoderInternal::FlacDecoderInternal(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/libnyquist/src/FlacDecoder.cpp:66
        #7 0x5636055361f0 in nqr::FlacDecoder::LoadFromPath(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/libnyquist/src/FlacDecoder.cpp:247
        #8 0x5636054e7e4d in nqr::NyquistIO::Load(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/libnyquist/src/Common.cpp:47
        #9 0x5636054cfaed in main /home/ubuntu/test/libnyquist/examples/src/Main.cpp:34
        #10 0x7efc72577082 in __libc_start_main ../csu/libc-start.c:308
        #11 0x5636054cf6dd in _start (/home/ubuntu/test/libnyquist/build/CMakeFiles/libnyquist-examples.dir/examples/src/example+0x826dd)
    
    AddressSanitizer can not provide additional info.
    SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0xbbc2f) 
    ==1646422==ABORTING
    

    Impact: An attacker can exploit this vulnerability by submitting a malicious elf file that exploits this bug which will result in a Denial of Service attack.

    opened by bladchan 0
  • Segmentation fault in nqr::linear_resample with a bad .flac input

    Segmentation fault in nqr::linear_resample with a bad .flac input

    Hi,

    I am running some experiments for AFLAPI and it has found a segmentation fault in nqr::linear_resample. This bug may allows attackers to cause DoS, so I report it here.

    Environment: Ubuntu 20.04 + g++ 9.6.0

    Test target: https://github.com/ddiakopoulos/libnyquist/blob/master/examples/src/Main.cpp

    Poc: segv.zip

    To reproduce:

    1. Complie the hole project with ASAN
    2. Complie the example with ASAN:
    [email protected]:~/test/libnyquist/build/CMakeFiles/libnyquist-examples.dir/examples/src$ g++ -fsanitize=address -o example Main.cpp.o AudioDevice.cpp.o -llibnyquist -lrtaudio
    
    1. Run:
    $ ./example ./segv.flac
    

    ASAN says:

    [email protected]:~/test/libnyquist/build/CMakeFiles/libnyquist-examples.dir/examples/src$ ./example ./segv.flac 
    [rtaudio] Found: 3 device(s)
    	Device: 0 - hw:Ensoniq AudioPCI,0
    	Device: 1 - hw:Ensoniq AudioPCI,1
    	Device: 2 - default
    
    [Warning - Sample Rate Mismatch] - file is sampled at 0 and output is 44100
    Input Samples: 0
    Playing STEREO for: -nan seconds...
    Output Samples: 0
    AddressSanitizer:DEADLYSIGNAL
    =================================================================
    ==1091132==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x556a7874ef66 bp 0x7ffecea08010 sp 0x7ffecea07f40 T0)
    ==1091132==The signal is caused by a READ memory access.
    ==1091132==Hint: address points to the zero page.
        #0 0x556a7874ef65 in nqr::linear_resample(double, std::vector<float, std::allocator<float> > const&, std::vector<float, std::allocator<float> >&, unsigned int) /home/ubuntu/test/libnyquist/include/libnyquist/Common.h:229
        #1 0x556a7874d358 in main /home/ubuntu/test/libnyquist/examples/src/Main.cpp:143
        #2 0x7f49d80eb082 in __libc_start_main ../csu/libc-start.c:308
        #3 0x556a7874c6dd in _start (/home/ubuntu/test/libnyquist/build/CMakeFiles/libnyquist-examples.dir/examples/src/example+0x826dd)
    
    AddressSanitizer can not provide additional info.
    SUMMARY: AddressSanitizer: SEGV /home/ubuntu/test/libnyquist/include/libnyquist/Common.h:229 in nqr::linear_resample(double, std::vector<float, std::allocator<float> > const&, std::vector<float, std::allocator<float> >&, unsigned int)
    ==1091132==ABORTING
    

    Issue code snippet:

    // libnyquist/include/libnyquist/Common.h:229
    220  inline void linear_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, const uint32_t samplesToProcess)
    221  {   // <---- It seems that check samplesToProcess == 0 can solve this bug?
    222      double virtualReadIndex = 0;
    223      double a, b, i, sample;
    224      uint32_t n = samplesToProcess - 1;  // samplesToProcess =0 --> n = -1 
    225      while (n--)  // --->overflow here!
    226      {
    227          uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
    228          i = virtualReadIndex - readIndex;
    229          a = input[readIndex + 0];
    230          b = input[readIndex + 1];
    231          sample = (1.0 - i) * a + i * b; // linear interpolate
    232          output.push_back(static_cast<float>(sample));
    233          virtualReadIndex += rate;
    234      }
    235  }
    

    Hope that helps.

    opened by bladchan 0
  • Versioning of libnyquist

    Versioning of libnyquist

    Hi,

    first: Thanks for providing such a useful and easy to use lib. This has been some awesome help for my own projects.

    It would be great to have some versioning of libnyquist to have some stable API, ABI and flags to build against. Are there any plans for versioning libnyquist? As e.g. one of my builds was broken with #60, it would be great to have some stable tags/version to build against.

    opened by Laguna1989 2
  • IMA ADPCM Stereo wav length half reduced

    IMA ADPCM Stereo wav length half reduced

    Hi.

    I'm using libnyquist. And found that while decoding wavs of type IMA ADPCM of two channels the length of the decoded file is reduced to half. If I add

            if (wavHeader.channel_count == 2)
              totalSamples *= 2;
    

    On WavDecoder.cpp line 309 the problem seems to be fixed.

    But I'm not sure if it is the right solution.

    Thanks.

    opened by q2p0 0
Owner
Dimitri Diakopoulos
Graphics, Engines, AR/VR
Dimitri Diakopoulos
Single file C library for decoding MPEG1 Video and MP2 Audio

PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer Single-file MIT licensed library for C/C++ See pl_mpeg.h for the documentation. Why?

Dominic Szablewski 605 Dec 27, 2022
Minimalistic MP3 decoder single header library

minimp3 Minimalistic, single-header library for decoding MP3. minimp3 is designed to be small, fast (with SSE and NEON support), and accurate (ISO con

Lion 1.2k Jan 4, 2023
A very simple example showing how to play mp3 files on the ESP32

ESP32 MP3 Player This repo contains a simple demonstration of how to play an MP3 file on the ESP32. You can configure the output to be either an I2S d

atomic14 38 Dec 23, 2022
MP3 Player/Organizer

I ♡ Music I ♡ Music is an MP3 player and organizer. It is designed for handling collections of albums in MP3 format, and it is very visual, attempting

Mattias Gustavsson 28 Dec 31, 2022
C library for cross-platform real-time audio input and output

libsoundio C library providing cross-platform audio input and output. The API is suitable for real-time software such as digital audio workstations as

Andrew Kelley 1.6k Jan 6, 2023
Tenacity is an easy-to-use, cross-platform multi-track audio editor/recorder for Windows, MacOS, GNU/Linux

Tenacity is an easy-to-use, cross-platform multi-track audio editor/recorder for Windows, MacOS, GNU/Linux and other operating systems and is developed by a group of volunteers as open source software.

null 59 Jan 1, 2023
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.

JUCE is an open-source cross-platform C++ application framework for creating high quality desktop and mobile applications, including VST, VST3, AU, AU

JUCE 4.7k Jan 6, 2023
Cross-platform silk codec wrap library depends on ploverlake/silk.

libSilkCodec Cross-platform silk codec wrap library depends on ploverlake/silk. Clone & Build Linux/Unix like # clone $ git clone https://github.c

KonataDev 8 Sep 9, 2022
🎵 A cross-platform media playback library for C/C++ with good number of features (only Windows & Linux).

libwinmedia A cross-platform media playback library for C/C++ & Flutter with good number of features. Example A very simple example can be as follows.

Harmonoid 38 Nov 2, 2022
projectM - cross-platform music visualization. Open-source and Milkdrop-compatible

projectM - cross-platform music visualization. Open-source and Milkdrop-compatible

projectM Visualizer 2.5k Dec 31, 2022
A tiny, header only, easy to use, cross-platform, portaudio wrapper, sound and notation manager, tailored for the demo scene.

TDAW A tiny, header only, easy to use, cross-platform, portaudio wrapper, sound and notation manager, tailored for the demo scene. This header enables

kbx 13 Dec 2, 2022
A simple C++ library for reading and writing audio files.

AudioFile A simple header-only C++ library for reading and writing audio files. Current supported formats: WAV AIFF Author AudioFile is written and ma

Adam Stark 683 Jan 4, 2023
A C library for reading and writing sound files containing sampled audio data.

libsndfile libsndfile is a C library for reading and writing files containing sampled audio data. Authors The libsndfile project was originally develo

null 1.1k Jan 2, 2023
C++ Audio and Music DSP Library

_____ _____ ___ __ _ _____ __ __ __ ____ ____ / \\_ \\ \/ / |/ \| | | | \_ \/ \ | Y Y \/ /_ \> <| | Y Y \ | |_|

Mick Grierson 1.4k Jan 7, 2023
Single file audio playback and capture library written in C.

A single file library for audio playback and capture. Example - Documentation - Supported Platforms - Backends - Major Features - Building - Unofficia

David Reid 2.6k Jan 8, 2023
C++17 library for creating macOS Audio Server plugins.

libASPL Synopsis Instructions Versioning API reference Example driver Quick start Object model Types of setters Customization Thread and realtime safe

Victor Gaydov 36 Dec 19, 2022
a library for audio and music analysis

aubio is a library to label music and sounds. It listens to audio signals and attempts to detect events. For instance, when a drum is hit, at which frequency is a note, or at what tempo is a rhythmic melody.

aubio 2.9k Jan 2, 2023
A discord audio playback library in c++ with node bindings

Tokio This project is still WIP. C++ Discord library with node bindings focused on audio playback. The Core parts as networking with discord/audio dec

Liz3 2 Nov 17, 2021