Add library: st_audiofile

This commit is contained in:
Jean Pierre Cimalando 2020-10-07 16:41:31 +02:00
parent a654458c55
commit ff1d749ee7
12 changed files with 699 additions and 0 deletions

4
.gitmodules vendored
View file

@ -19,3 +19,7 @@
path = editor/external/vstgui4 path = editor/external/vstgui4
url = https://github.com/sfztools/vstgui.git url = https://github.com/sfztools/vstgui.git
shallow = true shallow = true
[submodule "external/st_audiofile/thirdparty/dr_libs"]
path = external/st_audiofile/thirdparty/dr_libs
url = https://github.com/mackron/dr_libs.git
shallow = true

37
external/st_audiofile/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.5)
project(st_audiofile)
option(ST_AUDIO_FILE_USE_SNDFILE "Use sndfile" OFF)
set(ST_AUDIO_FILE_EXTERNAL_SNDFILE "" CACHE STRING "Name of external sndfile target")
add_library(st_audiofile STATIC
"src/st_audiofile.c"
"src/st_audiofile_common.c"
"src/st_audiofile_libs.c"
"src/st_audiofile_sndfile.c")
target_include_directories(st_audiofile
PUBLIC "src"
PUBLIC "thirdparty/dr_libs")
add_executable(st_info
"src/st_info.c")
target_link_libraries(st_info
PRIVATE st_audiofile)
if(ST_AUDIO_FILE_USE_SNDFILE)
target_compile_definitions(st_audiofile
PUBLIC "ST_AUDIO_FILE_USE_SNDFILE=1")
if(ST_AUDIO_FILE_EXTERNAL_SNDFILE)
target_link_libraries(st_audiofile
PRIVATE "${ST_AUDIO_FILE_EXTERNAL_SNDFILE}")
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(Sndfile "sndfile" REQUIRED)
target_include_directories(st_audiofile
PUBLIC ${Sndfile_INCLUDE_DIRS})
target_link_libraries(st_audiofile
PUBLIC ${Sndfile_LIBRARIES})
link_directories(
${Sndfile_LIBRARY_DIRS})
endif()
endif()

25
external/st_audiofile/LICENSE.md vendored Normal file
View file

@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2020, Jean-Pierre Cimalando
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

206
external/st_audiofile/src/st_audiofile.c vendored Normal file
View file

@ -0,0 +1,206 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "st_audiofile.h"
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
#include "st_audiofile_libs.h"
#include <stdlib.h>
struct st_audio_file {
int type;
union {
drwav *wav;
drflac *flac;
};
};
enum {
st_audio_file_null = -1,
};
st_audio_file* st_open_file(const char* filename)
{
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
if (!af)
return NULL;
af->type = st_audio_file_null;
if (af->type == st_audio_file_null) {
af->wav = (drwav*)malloc(sizeof(drwav));
if (!af->wav) {
free(af);
return NULL;
}
if (!drwav_init_file(af->wav, filename, NULL))
free(af->wav);
else
af->type = st_audio_file_wav;
}
if (af->type == st_audio_file_null) {
af->flac = drflac_open_file(filename, NULL);
if (af->flac)
af->type = st_audio_file_flac;
}
if (af->type == st_audio_file_null) {
free(af);
af = NULL;
}
return af;
}
#if defined(_WIN32)
st_audio_file* st_open_file_w(const wchar_t* filename)
{
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
if (!af)
return NULL;
af->type = st_audio_file_null;
if (af->type == st_audio_file_null) {
af->wav = (drwav*)malloc(sizeof(drwav));
if (!af->wav) {
free(af);
return NULL;
}
if (!drwav_init_file_w(af->wav, filename, NULL))
free(af->wav);
else
af->type = st_audio_file_wav;
}
if (af->type == st_audio_file_null) {
af->flac = drflac_open_file_w(filename, NULL);
if (af->flac)
af->type = st_audio_file_flac;
}
if (af->type == st_audio_file_null) {
free(af);
af = NULL;
}
return af;
}
#endif
void st_close(st_audio_file* af)
{
switch (af->type) {
case st_audio_file_wav:
drwav_uninit(af->wav);
free(af->wav);
break;
case st_audio_file_flac:
drflac_close(af->flac);
break;
}
af->type = st_audio_file_null;
}
int st_get_type(st_audio_file* af)
{
return af->type;
}
uint32_t st_get_channels(st_audio_file* af)
{
uint32_t channels = 0;
switch (af->type) {
case st_audio_file_wav:
channels = af->wav->channels;
break;
case st_audio_file_flac:
channels = af->flac->channels;
break;
}
return channels;
}
float st_get_sample_rate(st_audio_file* af)
{
float sample_rate = 0;
switch (af->type) {
case st_audio_file_wav:
sample_rate = af->wav->sampleRate;
break;
case st_audio_file_flac:
sample_rate = af->flac->sampleRate;
break;
}
return sample_rate;
}
uint64_t st_get_frame_count(st_audio_file* af)
{
uint64_t frames = 0;
switch (af->type) {
case st_audio_file_wav:
frames = af->wav->totalPCMFrameCount;
break;
case st_audio_file_flac:
frames = af->flac->totalPCMFrameCount;
break;
}
return frames;
}
bool st_seek(st_audio_file* af, uint64_t frame)
{
bool success = false;
switch (af->type) {
case st_audio_file_wav:
success = drwav_seek_to_pcm_frame(af->wav, frame);
break;
case st_audio_file_flac:
success = drflac_seek_to_pcm_frame(af->flac, frame);
break;
}
return success;
}
uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count)
{
switch (af->type) {
case st_audio_file_wav:
count = drwav_read_pcm_frames_s16(af->wav, count, buffer);
break;
case st_audio_file_flac:
count = drflac_read_pcm_frames_s16(af->flac, count, buffer);
break;
}
return count;
}
uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count)
{
switch (af->type) {
case st_audio_file_wav:
count = drwav_read_pcm_frames_f32(af->wav, count, buffer);
break;
case st_audio_file_flac:
count = drflac_read_pcm_frames_f32(af->flac, count, buffer);
break;
}
return count;
}
#endif // !defined(ST_AUDIO_FILE_USE_SNDFILE)

View file

@ -0,0 +1,52 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
#include <sndfile.h>
#endif
#include <stdint.h>
#include <stdbool.h>
#if defined(_WIN32)
#include <wchar.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct st_audio_file st_audio_file;
typedef enum st_audio_file_type {
st_audio_file_wav,
st_audio_file_flac,
st_audio_file_ogg,
st_audio_file_other,
} st_audio_file_type;
st_audio_file* st_open_file(const char* filename);
#if defined(_WIN32)
st_audio_file* st_open_file_w(const wchar_t* filename);
#endif
void st_close(st_audio_file* af);
int st_get_type(st_audio_file* af);
const char* st_get_type_string(st_audio_file* af);
const char* st_type_string(int type);
uint32_t st_get_channels(st_audio_file* af);
float st_get_sample_rate(st_audio_file* af);
uint64_t st_get_frame_count(st_audio_file* af);
bool st_seek(st_audio_file* af, uint64_t frame);
uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count);
uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count);
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
SNDFILE* st_get_sndfile_handle(st_audio_file* af);
int st_get_sndfile_format(st_audio_file* af);
#endif
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -0,0 +1,168 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include "st_audiofile.h"
class ST_AudioFile {
public:
constexpr ST_AudioFile() noexcept;
~ST_AudioFile() noexcept;
ST_AudioFile(ST_AudioFile&&) noexcept;
ST_AudioFile& operator=(ST_AudioFile&&) noexcept;
ST_AudioFile(const ST_AudioFile&) = delete;
ST_AudioFile& operator=(const ST_AudioFile&) = delete;
explicit operator bool() const noexcept;
void reset(st_audio_file* new_af = nullptr) noexcept;
bool open_file(const char* filename);
#if defined(_WIN32)
bool open_file_w(const wchar_t* filename);
#endif
int get_type() const noexcept;
const char* get_type_string() const noexcept;
static const char* type_string(int type) noexcept;
uint32_t get_channels() const noexcept;
float get_sample_rate() const noexcept;
uint64_t get_frame_count() const noexcept;
bool seek(uint64_t frame) noexcept;
uint64_t read_s16(int16_t* buffer, uint64_t count) noexcept;
uint64_t read_f32(float* buffer, uint64_t count) noexcept;
st_audio_file* get_handle() const noexcept;
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
void* get_sndfile_handle() const noexcept;
int get_sndfile_format() const noexcept;
#endif
private:
st_audio_file* af_ = nullptr;
};
//------------------------------------------------------------------------------
inline constexpr ST_AudioFile::ST_AudioFile() noexcept
{
}
inline ST_AudioFile::~ST_AudioFile() noexcept
{
reset();
}
ST_AudioFile::ST_AudioFile(ST_AudioFile&& other) noexcept
: af_(other.af_)
{
other.af_ = nullptr;
}
ST_AudioFile& ST_AudioFile::operator=(ST_AudioFile&& other) noexcept
{
if (this != &other) {
if (af_)
st_close(af_);
af_ = other.af_;
other.af_ = nullptr;
}
return *this;
}
inline ST_AudioFile::operator bool() const noexcept
{
return af_ != nullptr;
}
inline void ST_AudioFile::reset(st_audio_file* new_af) noexcept
{
if (af_ != new_af) {
if (af_)
st_close(af_);
af_ = new_af;
}
}
bool ST_AudioFile::open_file(const char* filename)
{
st_audio_file* new_af = st_open_file(filename);
reset(new_af);
return new_af != nullptr;
}
#if defined(_WIN32)
inline bool ST_AudioFile::open_file_w(const wchar_t* filename)
{
st_audio_file* new_af = st_open_file_w(filename);
reset(new_af);
return new_af != nullptr;
}
#endif
inline int ST_AudioFile::get_type() const noexcept
{
return st_get_type(af_);
}
inline const char* ST_AudioFile::get_type_string() const noexcept
{
return st_get_type_string(af_);
}
inline const char* ST_AudioFile::type_string(int type) noexcept
{
return st_type_string(type);
}
inline uint32_t ST_AudioFile::get_channels() const noexcept
{
return st_get_channels(af_);
}
inline float ST_AudioFile::get_sample_rate() const noexcept
{
return st_get_sample_rate(af_);
}
inline uint64_t ST_AudioFile::get_frame_count() const noexcept
{
return st_get_frame_count(af_);
}
inline bool ST_AudioFile::seek(uint64_t frame) noexcept
{
return st_seek(af_, frame);
}
inline uint64_t ST_AudioFile::read_s16(int16_t* buffer, uint64_t count) noexcept
{
return st_read_s16(af_, buffer, count);
}
inline uint64_t ST_AudioFile::read_f32(float* buffer, uint64_t count) noexcept
{
return st_read_f32(af_, buffer, count);
}
inline st_audio_file* ST_AudioFile::get_handle() const noexcept
{
return af_;
}
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
inline void* ST_AudioFile::get_sndfile_handle() const noexcept
{
return st_get_sndfile_handle(af_);
}
int ST_AudioFile::get_sndfile_format() const noexcept
{
return st_get_sndfile_format(af_);
}
#endif

View file

@ -0,0 +1,35 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "st_audiofile.h"
#include <stddef.h>
const char* st_get_type_string(st_audio_file* af)
{
return st_type_string(st_get_type(af));
}
const char* st_type_string(int type)
{
const char *type_string = NULL;
switch (type) {
case st_audio_file_wav:
type_string = "WAV";
break;
case st_audio_file_flac:
type_string = "FLAC";
break;
case st_audio_file_ogg:
type_string = "OGG";
break;
case st_audio_file_other:
type_string = "other";
break;
}
return type_string;
}

View file

@ -0,0 +1,9 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#define DR_WAV_IMPLEMENTATION
#define DR_FLAC_IMPLEMENTATION
#include "st_audiofile_libs.h"

View file

@ -0,0 +1,9 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include "dr_wav.h"
#include "dr_flac.h"

View file

@ -0,0 +1,120 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "st_audiofile.h"
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
#if defined(_WIN32)
#include <windows.h>
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
#endif
#include <sndfile.h>
#include <stdlib.h>
struct st_audio_file {
SNDFILE* snd;
SF_INFO info;
};
st_audio_file* st_open_file(const char* filename)
{
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
if (!af)
return NULL;
af->snd = sf_open(filename, SFM_READ, &af->info);
if (!af->snd) {
free(af);
return NULL;
}
return af;
}
#if defined(_WIN32)
st_audio_file* st_open_file_w(const wchar_t* filename)
{
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
if (!af)
return NULL;
af->snd = sf_wchar_open(filename, SFM_READ, &af->info);
if (!af->snd) {
free(af);
return NULL;
}
return af;
}
#endif
void st_close(st_audio_file* af)
{
if (af->snd) {
sf_close(af->snd);
af->snd = NULL;
}
}
int st_get_type(st_audio_file* af)
{
int type = st_audio_file_other;
switch (af->info.format & SF_FORMAT_TYPEMASK) {
case SF_FORMAT_WAV:
type = st_audio_file_wav;
break;
case SF_FORMAT_FLAC:
type = st_audio_file_flac;
break;
case SF_FORMAT_OGG:
type = st_audio_file_ogg;
break;
}
return type;
}
uint32_t st_get_channels(st_audio_file* af)
{
return af->info.channels;
}
float st_get_sample_rate(st_audio_file* af)
{
return af->info.samplerate;
}
uint64_t st_get_frame_count(st_audio_file* af)
{
return af->info.frames;
}
bool st_seek(st_audio_file* af, uint64_t frame)
{
return sf_seek(af->snd, frame, SEEK_SET) != -1;
}
uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count)
{
return sf_readf_short(af->snd, buffer, count);
}
uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count)
{
return sf_readf_float(af->snd, buffer, count);
}
SNDFILE* st_get_sndfile_handle(st_audio_file* af)
{
return af->snd;
}
int st_get_sndfile_format(st_audio_file* af)
{
return af->info.format;
}
#endif // defined(ST_AUDIO_FILE_USE_SNDFILE)

33
external/st_audiofile/src/st_info.c vendored Normal file
View file

@ -0,0 +1,33 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "st_audiofile.h"
#include <stdio.h>
#include <inttypes.h>
int main(int argc, char* argv[])
{
if (argc != 2) {
fprintf(stderr, "Please indicate a sound file.\n");
return 1;
}
const char* filename = argv[1];
st_audio_file* af = st_open_file(filename);
if (!af) {
fprintf(stderr, "Could not open the sound file.\n");
return 1;
}
printf("File name : %s\n", filename);
printf("File type : %s\n", st_get_type_string(af));
printf("Channels : %u\n", st_get_channels(af));
printf("Sample rate : %f\n", st_get_sample_rate(af));
printf("Frames : %" PRIu64 "\n", st_get_frame_count(af));
return 0;
}

@ -0,0 +1 @@
Subproject commit cac1785cee4abb455817b43d5dee33b49d61be2f