GithubHelp home page GithubHelp logo

ddiakopoulos / libnyquist Goto Github PK

View Code? Open in Web Editor NEW
529.0 23.0 64.0 33.71 MB

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

License: BSD 2-Clause "Simplified" License

C 12.49% C++ 79.25% CMake 8.26%
cpp11 audio audio-library ogg wav opus flac gamedev mp3 audio-engine

libnyquist's Introduction

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.

libnyquist's People

Contributors

4321ba avatar arthursonzogni avatar avaer avatar ddiakopoulos avatar juliusikkala avatar laguna1989 avatar mallgrab avatar meshula avatar mikeperri avatar nasso avatar phniix avatar r-lyeh avatar raub avatar samvanheer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libnyquist's Issues

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.

COM version?

Hi all :)

Is there any chance of a COM wrapper for this DLL? So that it can be used from ASP/VBscript....

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

NyquistIO::Load creates temporary map every time it's called

The function NyquistIO::Load(AudioData * data, const std::vector<uint8_t> & buffer) creates a temporary map of magic identifiers to extensions every time it's called. Since this is a read-only map it's probably best to make this a global constant to eliminate the overhead.

The function also continues scanning for magic after it's found a match, is that required? Otherwise i'll make a separate issue for that.

Compile error on Linux and macOS

When trying to compile on Linux or macOS with the Clang++ compiler, I get assembly errors:

../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1830:9: error: unknown use of instruction mnemonic without a size suffix
        add     edi, eax                    ; add to running sum
        ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1830:54: error: unexpected token in argument list
        add     edi, eax                    ; add to running sum
                                                     ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1831:9: error: unknown use of instruction mnemonic without a size suffix
L45:    sub     ebx, 1
        ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1836:9: error: unknown use of instruction mnemonic without a size suffix
        mov     edi, -1                     ; return -1 to indicate limit hit
        ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1836:57: error: unexpected token in argument list
        mov     edi, -1                     ; return -1 to indicate limit hit
                                                        ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1838:9: error: unknown use of instruction mnemonic without a size suffix
        mov     eax, edi                    ; move sum accumulator into eax for return
        ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1838:56: error: unexpected token in argument list
        mov     eax, edi                    ; move sum accumulator into eax for return
                                                       ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1840:9: error: unknown use of instruction mnemonic without a size suffix
        add     rsp, 8                      ; begin epilog by deallocating stack
        ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1840:60: error: unexpected token in argument list
        add     rsp, 8                      ; begin epilog by deallocating stack
                                                           ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1841:68: error: unexpected token in argument list
        pop     rsi                         ; restore non-volatile registers & return
                                                                   ^
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1847:1: error: invalid instruction mnemonic 'log2buffer_x64win'
log2buffer_x64win endp
^~~~~~~~~~~~~~~~~
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1849:1: error: invalid instruction mnemonic 'asmcode'
asmcode ends
^~~~~~~
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1851:9: error: invalid instruction mnemonic 'end'
        end
        ^~~
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x64.asm:1746:16: error: directional label undefined
        byte   03f, 041, 042, 043, 044, 045, 047, 048, 049, 04a, 04b, 04d, 04e, 04f, 050, 05

Additionally with g++ on linux, I get this error instead:

RavEngine/deps/libnyquist/CMakeFiles/libwavpack.dir/third_party/wavpack/src/pack_x86.S.o 
/usr/bin/cc  -I../RavEngine/deps/libnyquist/third_party/wavpack/include -O2 -DNDEBUG -MD -MT RavEngine/deps/libnyquist/CMakeFiles/libwavpack.dir/third_party/wavpack/src/pack_x86.S.o -MF RavEngine/deps/libnyquist/CMakeFiles/libwavpack.dir/third_party/wavpack/src/pack_x86.S.o.d -o RavEngine/deps/libnyquist/CMakeFiles/libwavpack.dir/third_party/wavpack/src/pack_x86.S.o -c ../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S: Assembler messages:
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:85: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:86: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:87: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:88: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:477: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:478: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:479: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:480: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:536: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:538: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:539: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:540: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:547: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:549: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:550: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:551: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:934: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:935: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:936: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1071: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1072: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1073: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1074: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1076: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1077: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1349: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1350: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1351: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1352: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1353: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1354: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1397: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1399: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1400: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1401: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1410: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1412: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1414: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1561: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1562: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1563: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1564: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1600: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1601: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1602: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1603: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1669: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1670: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1671: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1672: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1724: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1725: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1726: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1727: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1735: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1803: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1804: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1805: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1806: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1815: Error: invalid instruction suffix for `pushf'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1816: Error: invalid instruction suffix for `pushf'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1818: Error: invalid instruction suffix for `popf'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1819: Error: invalid instruction suffix for `pushf'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1820: Error: operand type mismatch for `pop'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1822: Error: invalid instruction suffix for `popf'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1826: Error: operand type mismatch for `push'
../RavEngine/deps/libnyquist/third_party/wavpack/src/pack_x86.S:1833: Error: operand type mismatch for `pop'

This began when trying to integrate the rlottie library alongside this library, though I'm not sure what's causing it in rlottie's CMakeLists.

I am building libnyquist like this:

# libnyquist
SET(BUILD_EXAMPLE OFF CACHE INTERNAL "")
add_subdirectory("${DEPS_DIR}/libnyquist")

target_link_libraries("${PROJECT_NAME}" PRIVATE 
	# .....
	"libnyquist"
	PUBLIC
       # .....
)
# .....

clang++ info

clang version 10.0.1 (Fedora 10.0.1-3.fc32)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

g++ info

gcc (GCC) 10.2.1 20201125 (Red Hat 10.2.1-9)

NyquistIO::Load -> from Buffer - leaves a hole of an open unpropagated exception to the caller

Any plausible std::exception raised by decoder->LoadFromBuffer(data, buffer); is not propagated to the caller. This impacts certain load operations not handled by the library.

See here:

decoder->LoadFromBuffer(data, buffer);

A recent change was made in f94005c that rethrew an exception from the file path version of the load. It would be handy if the re-throw also occurred for those users that perform buffer based operations.

Use cmake FetchContent, instead of copying 3rd parties?

One possible improvement to this library.
Maybe CMake FetchContent could be used:
https://cmake.org/cmake/help/v3.11/module/FetchContent.html

libnyquist include many other libraries by copy-pasting them. Maybe you can move them out of libnyquist and get them at configure time:

FetchContent_Declare(opus
  GIT_REPOSITORY https://github.com/xiph/opus
  GIT_TAG v1.3.1
)

FetchContent_GetProperties(opus)
if(NOT opus_POPULATED)
  FetchContent_Populate(opus)
  // Do whatever you want in ${opus_SOURCE_DIR}
endif()

OpusDependencies.c ⇒ implicit declaration of function is invalid in C99

I have one remaining error when I try to use libnyquist with WebAssembly.

Repro steps:
Install emscripten SDK. Then:

mkdir build_emscripen
cd build_emscripten
emcmake cmake ..
make -j

Errors:

In file included from /home/sonzogna/programmation/download/libnyquist/src/OpusDependencies.c:96:
/home/sonzogna/programmation/download/libnyquist/third_party/opus/celt/celt_decoder.c:102:11: error: 
      implicit declaration of function 'opus_custom_decoder_get_size' is invalid in C99
      [-Werror,-Wimplicit-function-declaration]
   return opus_custom_decoder_get_size(mode, channels);

I am not quite sure what is the problem.

C API

Wrap existing C++ API

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 ™️ ? :)

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/

Undefined reference to WavpackGetNumSamples (Raspberry Pi Target)

Hello!

When I use the library in my project, at compile time on a Raspberry Pi (with Raspbian up to date), I have this error:

WavPackDecoder.cpp:(.text._ZNK15WavPackInternal15getTotalSamplesEv[_ZNK15WavPackInternal15getTotalSamplesEv]+0x1c): undefined reference to WavpackGetNumSamples' /usr/local/lib/liblibnyquist.a(WavPackDecoder.cpp.o): In function WavPackInternal::getLengthInSeconds() const':
WavPackDecoder.cpp:(.text._ZNK15WavPackInternal18getLengthInSecondsEv[_ZNK15WavPackInternal18getLengthInSecondsEv]+0x2c): undefined reference to `WavpackGetSampleRate'
collect2: error: ld returned 1 exit status
make: *** [Makefile:17: CapProject3] Error 1

What should I do?

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?

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.

AddressSanitizer: heap-buffer-overflow

I updated libnyquist.

On 59e4be4, I got this error with ASAN:

==166518==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62c000007836 at pc 0x55dc58b8b808 bp 0x7fff7ece96c0 sp 0x7fff7ece96b0
READ of size 2 at 0x62c000007836 thread T0
    #0 0x55dc58b8b807 in nqr::ScanForChunk(std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned int) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/include/libnyquist/Common.h:587
    #1 0x55dc58b8a652 in nqr::WavDecoder::LoadFromBuffer(nqr::AudioData*, std::vector<unsigned char, std::allocator<unsigned char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/src/WavDecoder.cpp:269
    #2 0x55dc58b896d5 in nqr::WavDecoder::LoadFromPath(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/src/WavDecoder.cpp:143
    #3 0x55dc588c8ed0 in nqr::NyquistIO::Load(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/src/Common.cpp:47
    #4 0x55dc58647fe4 in smk::SoundBuffer::SoundBuffer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/smk-src/src/smk/SoundBuffer.cpp:35
    #5 0x55dc58439e5e in term_breaker::LoadResources() /home/arthursonzogni/programmation/real/termRider/src/resources.cpp:83
    #6 0x55dc583dd2da in term_breaker::StartGame() /home/arthursonzogni/programmation/real/termRider/src/game.cpp:142
    #7 0x55dc583d85d5 in main /home/arthursonzogni/programmation/real/termRider/src/main.cpp:5
    #8 0x7fe06482350f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #9 0x7fe0648235c8 in __libc_start_main_impl ../csu/libc-start.c:381
    #10 0x55dc583d8504 in _start (/home/arthursonzogni/programmation/real/termRider/build/termBreaker+0x276504)

0x62c000007836 is located 0 bytes to the right of 30262-byte region [0x62c000000200,0x62c000007836)
allocated by thread T0 here:
    #0 0x7fe065ac0488 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55dc588ded09 in std::__new_allocator<unsigned char>::allocate(unsigned long, void const*) /usr/include/c++/12/bits/new_allocator.h:137
    #2 0x55dc588dd3ff in std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned long) /usr/include/c++/12/bits/alloc_traits.h:464
    #3 0x55dc588daf7b in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_allocate(unsigned long) /usr/include/c++/12/bits/stl_vector.h:378
    #4 0x55dc588d7d2e in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_create_storage(unsigned long) /usr/include/c++/12/bits/stl_vector.h:395
    #5 0x55dc588d431e in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_Vector_base(unsigned long, std::allocator<unsigned char> const&) /usr/include/c++/12/bits/stl_vector.h:332
    #6 0x55dc588d13c0 in std::vector<unsigned char, std::allocator<unsigned char> >::vector(unsigned long, std::allocator<unsigned char> const&) (/home/arthursonzogni/programmation/real/termRider/build/termBreaker+0x76f3c0)
    #7 0x55dc588cb2aa in nqr::ReadFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/src/Common.cpp:210
    #8 0x55dc58b896b8 in nqr::WavDecoder::LoadFromPath(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/src/WavDecoder.cpp:142
    #9 0x55dc588c8ed0 in nqr::NyquistIO::Load(nqr::AudioData*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/libnyquist-src/src/Common.cpp:47
    #10 0x55dc58647fe4 in smk::SoundBuffer::SoundBuffer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/arthursonzogni/programmation/real/termRider/build/_deps/smk-src/src/smk/SoundBuffer.cpp:35
    #11 0x55dc58439e5e in term_breaker::LoadResources() /home/arthursonzogni/programmation/real/termRider/src/resources.cpp:83
    #12 0x55dc583dd2da in term_breaker::StartGame() /home/arthursonzogni/programmation/real/termRider/src/game.cpp:142
    #13 0x55dc583d85d5 in main /home/arthursonzogni/programmation/real/termRider/src/main.cpp:5
    #14 0x7fe06482350f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

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:
ubuntu@ubuntu:~/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:

ubuntu@ubuntu:~/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.

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.

Metadata Probe

Expose API to fill out AudioData struct without decoding the audio. Basically extract all the metadata and computed fields.

Normalization

Hello,

I'm using libnyquist for a pitch tracking application. I decode the audio from a wav file, and run it through some algorithms (Mcleod, YIN, etc.)

For a few minutes I was scratching my head about why I was getting completely wrong results until I noticed the normalized between [-1.0, 1.0] part of the README. When I multiply the samples vector output by the decoder by a constant e.g. 100 or 1000 to amplify the signal, my pitch tracking algorithms produce correct results.

My question is,

  • Is my approach correct? This decoder library outputting normalized audio data and clients multiplying the vector by a scalar factor to amplify it? Does that introduce any problems, is there a better way for me to achieve that? Modify my pitch tracking code to operate on normalized values?
  • Could that behavior be modified in this library? Or is normalized output always desired/mandatory

MIME Type / Resource Loader

Implement API functionality to take an audio file and dispatch to the correct decoder automatically.

Related Functions:

  • Check if supported file format for decoding
  • Check if supported file format for encoding

Version libvorbis

Hi Ddiakopoulos,
Can i know the right version number for the libvorbis because i don't have the information in your files ?

Regards,

Domingues Fabien

shouldn't rely on file extension

libnyquist decodes "myfile.mp3" just fine.

But if I rename it to "myfile.data", it gives some kind of format error.

Shouldn't the library read the header from the beginning of the file, instead of relying on the file extension?

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?

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.

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:
ubuntu@ubuntu:~/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:

ubuntu@ubuntu:~/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.

/arch:AVX causes a crash on some older CPU models

With this instruction set the MSVC emits unconditional usage of the instructions vpxor and vmovdqu when constructing a std::shared_ptr. On older CPU models that don't support the AVX instruction set this will result in a crash. It was quite frustrating to figure this out given that less than 1% of my users appear to be affected.
Maybe this instruction set could not be unconditionally applied to libnyquist when built from CMake? Or maybe the usage of std::shared_ptr can be reduced. Given that all decoders are stateless and 1-byte large there's next to not good reason to use std::shared_ptr for their storage. Although it has been a while since I worked with C++11, maybe something prevents you from avoid that.

mingw: unrecognized options and linking error

Hi!
I'm trying to cross-compile my project, including this library from ubuntu 20.04 to windows with mingw-w64 7.0.0-2, with this toolchain cmake file and I get this error:

x86_64-w64-mingw32-gcc: error: /arch:AVX: No such file or directory
x86_64-w64-mingw32-gcc: error: /Zi: No such file or directory

which I found in cmake/CXXhelpers.cmake
so my guess is that mingw doesn't know these options (and it expects dashes instead of slashes anyway)
commenting out line 18 seemed to work

however now I'm getting linking errors:

/usr/bin/x86_64-w64-mingw32-ld: bin/liblibnyquist.a(FlacDependencies.c.obj):FlacDependencies.c:(.text+0x1a6d2): undefined reference to `fopen_utf8'
/usr/bin/x86_64-w64-mingw32-ld: bin/liblibnyquist.a(FlacDependencies.c.obj):FlacDependencies.c:(.text+0x1a7b2): undefined reference to `fopen_utf8'

I actually don't need flac, nor libnyquist to manage fileio, so I just tried commenting out stuff so that it at least compiles but I just generated more errors instead. (Should I use a different library if I don't need half the stuff?)
Can someone push me in the right direction?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.