Add sound file decoding support with libsndfile
This commit is contained in:
parent
09ba2d297c
commit
03693c6d06
68
include/audio/error.hpp
Normal file
68
include/audio/error.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of the WyZ project
|
||||||
|
Copyright (C) 2020 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OUR_DICK_AUDIO_ERROR_HPP
|
||||||
|
#define OUR_DICK_AUDIO_ERROR_HPP
|
||||||
|
|
||||||
|
namespace audio{
|
||||||
|
|
||||||
|
class error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum err{
|
||||||
|
NONE = 0,
|
||||||
|
UNSUPPORTED_FORMAT,
|
||||||
|
SYSTEM,
|
||||||
|
BAD_FILE,
|
||||||
|
UNSUPPORTED_ENCODING,
|
||||||
|
INVALID_CHANNEL_COUNT,
|
||||||
|
INVALID_SAMPLE_RATE,
|
||||||
|
INVALID_DEVICE,
|
||||||
|
INVALID_FLAG,
|
||||||
|
BAD_DEVICE_COMBO,
|
||||||
|
OUT_OF_MEMORY,
|
||||||
|
BUFFER_TOO_BIG,
|
||||||
|
BUFFER_TOO_SMALL,
|
||||||
|
BAD_CALLBACK,
|
||||||
|
BAD_STREAM,
|
||||||
|
TIMED_OUT,
|
||||||
|
STREAM_STOPPED,
|
||||||
|
STREAM_NOT_STOPPED,
|
||||||
|
INPUT_OVERFLOW,
|
||||||
|
OUTPUT_UNDERFLOW,
|
||||||
|
BAD_BUFFER,
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
int m_actual;
|
||||||
|
int m_homog;
|
||||||
|
|
||||||
|
public:
|
||||||
|
error(int actual);
|
||||||
|
error(const error&) = default;
|
||||||
|
error(error&&) = default;
|
||||||
|
~error() = default;
|
||||||
|
error& operator=(const error&) = default;
|
||||||
|
error& operator=(error&&) = default;
|
||||||
|
|
||||||
|
operator int()const;
|
||||||
|
int get()const;
|
||||||
|
int get_raw()const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
32
include/audio/frame_fmt.hpp
Normal file
32
include/audio/frame_fmt.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2020 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OUR_DICK_AUDIO_FRAME_FMT_HPP
|
||||||
|
#define OUR_DICK_AUDIO_FRAME_FMT_HPP
|
||||||
|
|
||||||
|
#include <portaudio.h>
|
||||||
|
|
||||||
|
namespace audio{
|
||||||
|
|
||||||
|
enum class frame_fmt{
|
||||||
|
float32 = paFloat32,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -23,9 +23,12 @@ namespace audio{
|
|||||||
|
|
||||||
class pa_system
|
class pa_system
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
pa_system();
|
pa_system();
|
||||||
~pa_system();
|
~pa_system();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static pa_system& instance();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
90
include/audio/sndrd.hpp
Normal file
90
include/audio/sndrd.hpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2020 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OUR_DICK_SNDRD_HPP
|
||||||
|
#define OUR_DICK_SNDRD_HPP
|
||||||
|
|
||||||
|
#include <sndfile.h>
|
||||||
|
#include <cstddef> //size_t
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "error.hpp"
|
||||||
|
|
||||||
|
namespace audio{
|
||||||
|
|
||||||
|
class sndrd
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SF_INFO m_info = {};
|
||||||
|
SNDFILE* m_fp = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class mode : int{
|
||||||
|
r = SFM_READ,
|
||||||
|
w = SFM_WRITE,
|
||||||
|
rw = SFM_RDWR,
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
constexpr sndrd(void)noexcept = default;
|
||||||
|
sndrd(const char* f, mode m = mode::r)noexcept;
|
||||||
|
sndrd(const sndrd&) = delete;
|
||||||
|
sndrd(sndrd&& f)noexcept;
|
||||||
|
~sndrd(void)noexcept;
|
||||||
|
sndrd& operator=(const sndrd&) = delete;
|
||||||
|
sndrd& operator=(sndrd&& f)noexcept;
|
||||||
|
|
||||||
|
SNDFILE* release(void)noexcept;
|
||||||
|
|
||||||
|
//Returns length in frames
|
||||||
|
size_t length(void)noexcept;
|
||||||
|
//Returns position in frames
|
||||||
|
size_t position(void)const noexcept;
|
||||||
|
void set_pos(size_t newpos)noexcept;
|
||||||
|
void seek(long int offset)noexcept;
|
||||||
|
|
||||||
|
operator SNDFILE*(void)noexcept;
|
||||||
|
operator const SNDFILE*(void)const noexcept;
|
||||||
|
SNDFILE* get(void)noexcept;
|
||||||
|
const SNDFILE* get(void)const noexcept;
|
||||||
|
bool valid()const noexcept;
|
||||||
|
|
||||||
|
size_t read(float* dest, size_t items)noexcept;
|
||||||
|
size_t read_frames(float* dest, size_t frames)noexcept;
|
||||||
|
//TODO other formats
|
||||||
|
|
||||||
|
size_t write(const float* src, size_t items)noexcept;
|
||||||
|
size_t write_frames(const float* src, size_t frames)noexcept;
|
||||||
|
//TODO other formats
|
||||||
|
|
||||||
|
void close()noexcept;
|
||||||
|
|
||||||
|
//getters
|
||||||
|
size_t frames()const noexcept;
|
||||||
|
int samplerate()const noexcept;
|
||||||
|
int channels()const noexcept;
|
||||||
|
int file_format()const noexcept;
|
||||||
|
int sections()const noexcept;
|
||||||
|
bool seekable()const noexcept;
|
||||||
|
|
||||||
|
error last_error()const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -24,44 +24,41 @@
|
|||||||
|
|
||||||
#include "detail/utility.hpp"
|
#include "detail/utility.hpp"
|
||||||
#include "detail.hpp"
|
#include "detail.hpp"
|
||||||
|
#include "error.hpp"
|
||||||
|
|
||||||
namespace audio{
|
namespace audio{
|
||||||
|
|
||||||
enum class stream_fmt{
|
|
||||||
float32 = paFloat32,
|
|
||||||
};
|
|
||||||
|
|
||||||
class stream
|
class stream
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
detail::callback_iface* m_cb = nullptr;
|
detail::callback_iface* m_cb = nullptr;
|
||||||
PaStream* m_stream = nullptr;
|
PaStream* m_stream = nullptr;
|
||||||
PaError m_err = paNoError;
|
mutable PaError m_err = paNoError;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename Callback, typename... Args>
|
template<typename Callback, typename... Args>
|
||||||
stream(int in_c, int out_c, stream_fmt fmt, double samplerate, size_t buffersize, Callback&& cb, Args&&... cbargs):
|
stream(int in_c, int out_c, double samplerate, size_t buffersize, Callback&& cb, Args&&... cbargs):
|
||||||
m_cb(new detail::callback_impl<Callback,Args...>(std::forward<Callback>(cb), std::forward<Args>(cbargs)...)),
|
m_cb(new detail::callback_impl<Callback,Args...>(std::forward<Callback>(cb), std::forward<Args>(cbargs)...)),
|
||||||
m_stream(initialize_global_instance()),
|
m_stream(initialize_global_instance()),
|
||||||
m_err(open_default_stream(&m_stream, in_c, out_c, fmt, samplerate, buffersize, m_cb)){}
|
m_err(open_default_stream(&m_stream, in_c, out_c, paFloat32, samplerate, buffersize, m_cb)){}
|
||||||
|
|
||||||
~stream();
|
~stream();
|
||||||
|
|
||||||
int start();
|
error start();
|
||||||
int stop();
|
error stop();
|
||||||
int abort();
|
error abort();
|
||||||
int close();
|
error close();
|
||||||
|
|
||||||
bool is_stopped()const;
|
bool is_stopped()const;
|
||||||
bool is_active()const;
|
bool is_active()const;
|
||||||
|
|
||||||
int last_error()const;
|
error last_error()const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static PaStream* initialize_global_instance();
|
static PaStream* initialize_global_instance();
|
||||||
//to avoid using portaudio functions in the header
|
//to avoid using portaudio functions in the header
|
||||||
static int open_default_stream(PaStream**, int in_c, int out_c,
|
static int open_default_stream(PaStream**, int in_c, int out_c,
|
||||||
stream_fmt fmt, double samplerate,
|
int fmt, double samplerate,
|
||||||
size_t bufsize, detail::callback_iface* cb);
|
size_t bufsize, detail::callback_iface* cb);
|
||||||
static int callback(const void* input, void* output, unsigned long framecount,
|
static int callback(const void* input, void* output, unsigned long framecount,
|
||||||
const PaStreamCallbackTimeInfo* /*timeInfo*/, PaStreamCallbackFlags /*statusFlags*/,
|
const PaStreamCallbackTimeInfo* /*timeInfo*/, PaStreamCallbackFlags /*statusFlags*/,
|
||||||
|
|||||||
2
makefile
2
makefile
@ -40,7 +40,7 @@ ifneq ($(WINDOWS),1)
|
|||||||
CC::=gcc
|
CC::=gcc
|
||||||
CXX::=g++
|
CXX::=g++
|
||||||
LDLIBS::=
|
LDLIBS::=
|
||||||
LDFLAGS::= -lglfw -lgl3w -ldl -lm -lportaudio -lasound
|
LDFLAGS::= -lglfw -lgl3w -ldl -lm -lportaudio -lasound -lsndfile
|
||||||
STRIP::=strip
|
STRIP::=strip
|
||||||
RANLIB::=ranlib
|
RANLIB::=ranlib
|
||||||
AR::=ar
|
AR::=ar
|
||||||
|
|||||||
105
src/audio/error.cpp
Normal file
105
src/audio/error.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of the WyZ project
|
||||||
|
Copyright (C) 2020 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "audio/error.hpp"
|
||||||
|
|
||||||
|
#include <portaudio.h>
|
||||||
|
#include <sndfile.h>
|
||||||
|
|
||||||
|
namespace audio{
|
||||||
|
|
||||||
|
static int map_lib_errors(int liberr){
|
||||||
|
//portaudio and sndfile have no error overlaps, so a switch covers both
|
||||||
|
switch(liberr){
|
||||||
|
default:
|
||||||
|
case SF_ERR_NO_ERROR:
|
||||||
|
//case paNoError: //same value as SF_ERR_NO_ERROR
|
||||||
|
return error::NONE;
|
||||||
|
case paSampleFormatNotSupported:
|
||||||
|
case SF_ERR_UNRECOGNISED_FORMAT:
|
||||||
|
return error::UNSUPPORTED_FORMAT;
|
||||||
|
case SF_ERR_MALFORMED_FILE:
|
||||||
|
return error::BAD_FILE;
|
||||||
|
case SF_ERR_UNSUPPORTED_ENCODING:
|
||||||
|
return error::UNSUPPORTED_ENCODING;
|
||||||
|
|
||||||
|
case paInvalidChannelCount:
|
||||||
|
return error::INVALID_CHANNEL_COUNT;
|
||||||
|
case paInvalidSampleRate:
|
||||||
|
return error::INVALID_SAMPLE_RATE;
|
||||||
|
case paDeviceUnavailable:
|
||||||
|
case paInvalidDevice:
|
||||||
|
return error::INVALID_DEVICE;
|
||||||
|
case paInvalidFlag:
|
||||||
|
return error::INVALID_FLAG;
|
||||||
|
case paBadIODeviceCombination:
|
||||||
|
return error::BAD_DEVICE_COMBO;
|
||||||
|
case paInsufficientMemory:
|
||||||
|
return error::OUT_OF_MEMORY;
|
||||||
|
case paBufferTooBig:
|
||||||
|
return error::BUFFER_TOO_BIG;
|
||||||
|
case paBufferTooSmall:
|
||||||
|
return error::BUFFER_TOO_SMALL;
|
||||||
|
case paNullCallback:
|
||||||
|
return error::BAD_CALLBACK;
|
||||||
|
case paCanNotReadFromACallbackStream:
|
||||||
|
case paCanNotWriteToACallbackStream:
|
||||||
|
case paCanNotReadFromAnOutputOnlyStream:
|
||||||
|
case paCanNotWriteToAnInputOnlyStream:
|
||||||
|
case paBadStreamPtr:
|
||||||
|
return error::BAD_STREAM;
|
||||||
|
case paTimedOut:
|
||||||
|
return error::TIMED_OUT;
|
||||||
|
case paStreamIsStopped:
|
||||||
|
return error::STREAM_STOPPED;
|
||||||
|
case paStreamIsNotStopped:
|
||||||
|
return error::STREAM_NOT_STOPPED;
|
||||||
|
case paInputOverflowed:
|
||||||
|
return error::INPUT_OVERFLOW;
|
||||||
|
case paOutputUnderflowed:
|
||||||
|
return error::OUTPUT_UNDERFLOW;
|
||||||
|
case paBadBufferPtr:
|
||||||
|
return error::BAD_BUFFER;
|
||||||
|
|
||||||
|
case paIncompatibleStreamHostApi:
|
||||||
|
case paInvalidHostApi:
|
||||||
|
case paHostApiNotFound:
|
||||||
|
case paIncompatibleHostApiSpecificStreamInfo:
|
||||||
|
case paInternalError:
|
||||||
|
case paNotInitialized:
|
||||||
|
case paUnanticipatedHostError:
|
||||||
|
case SF_ERR_SYSTEM:
|
||||||
|
return error::SYSTEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error::error(int actual):
|
||||||
|
m_actual(actual),
|
||||||
|
m_homog(map_lib_errors(actual)){}
|
||||||
|
|
||||||
|
error::operator int()const{
|
||||||
|
return m_homog;
|
||||||
|
}
|
||||||
|
int error::get()const{
|
||||||
|
return m_homog;
|
||||||
|
}
|
||||||
|
int error::get_raw()const{
|
||||||
|
return m_actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -41,4 +41,8 @@ namespace audio{
|
|||||||
Pa_Terminate();
|
Pa_Terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pa_system& pa_system::instance(){
|
||||||
|
static pa_system inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
119
src/audio/sndrd.cpp
Normal file
119
src/audio/sndrd.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2020 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "audio/sndrd.hpp"
|
||||||
|
#include "audio/error.hpp"
|
||||||
|
|
||||||
|
#include <utility> //exchange, swap
|
||||||
|
|
||||||
|
namespace audio{
|
||||||
|
|
||||||
|
sndrd::sndrd(const char* f, mode m)noexcept:
|
||||||
|
m_info(),
|
||||||
|
m_fp(sf_open(f, static_cast<int>(m), &m_info)){}
|
||||||
|
sndrd::sndrd(sndrd&& f)noexcept:
|
||||||
|
m_info(f.m_info),
|
||||||
|
m_fp(std::exchange(f.m_fp, nullptr)){}
|
||||||
|
sndrd::~sndrd()noexcept{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
sndrd& sndrd::operator=(sndrd&& f)noexcept{
|
||||||
|
std::swap(m_fp, f.m_fp);
|
||||||
|
m_info = f.m_info;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNDFILE* sndrd::release()noexcept{
|
||||||
|
return std::exchange(m_fp, nullptr);
|
||||||
|
}
|
||||||
|
size_t sndrd::length()noexcept{
|
||||||
|
size_t pos = position();
|
||||||
|
size_t len = sf_seek(m_fp, 0, SEEK_END);
|
||||||
|
sf_seek(m_fp, pos, SEEK_SET);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
size_t sndrd::position()const noexcept{
|
||||||
|
return sf_seek(m_fp, 0, SEEK_CUR);
|
||||||
|
}
|
||||||
|
void sndrd::set_pos(size_t newpos)noexcept{
|
||||||
|
sf_seek(m_fp, newpos, SEEK_SET);
|
||||||
|
}
|
||||||
|
void sndrd::seek(long int offset)noexcept{
|
||||||
|
size_t pos = position();
|
||||||
|
sf_seek(m_fp, pos + offset, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
sndrd::operator SNDFILE*()noexcept{
|
||||||
|
return m_fp;
|
||||||
|
}
|
||||||
|
sndrd::operator const SNDFILE*()const noexcept{
|
||||||
|
return m_fp;
|
||||||
|
}
|
||||||
|
SNDFILE* sndrd::get()noexcept{
|
||||||
|
return m_fp;
|
||||||
|
}
|
||||||
|
const SNDFILE* sndrd::get()const noexcept{
|
||||||
|
return m_fp;
|
||||||
|
}
|
||||||
|
bool sndrd::valid()const noexcept{
|
||||||
|
return m_fp && !last_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sndrd::read(float* dest, size_t items)noexcept{
|
||||||
|
return sf_read_float(m_fp, dest, items);
|
||||||
|
}
|
||||||
|
size_t sndrd::read_frames(float* dest, size_t frames)noexcept{
|
||||||
|
return sf_readf_float(m_fp, dest, frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sndrd::write(const float* src, size_t items)noexcept{
|
||||||
|
return sf_write_float(m_fp, src, items);
|
||||||
|
}
|
||||||
|
size_t sndrd::write_frames(const float* src, size_t frames)noexcept{
|
||||||
|
return sf_writef_float(m_fp, src, frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sndrd::close()noexcept{
|
||||||
|
if(m_fp)
|
||||||
|
sf_close(m_fp);
|
||||||
|
m_fp = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sndrd::frames()const noexcept{
|
||||||
|
return m_info.frames;
|
||||||
|
}
|
||||||
|
int sndrd::samplerate()const noexcept{
|
||||||
|
return m_info.samplerate;
|
||||||
|
}
|
||||||
|
int sndrd::channels()const noexcept{
|
||||||
|
return m_info.channels;
|
||||||
|
}
|
||||||
|
int sndrd::file_format()const noexcept{
|
||||||
|
return m_info.format;
|
||||||
|
}
|
||||||
|
int sndrd::sections()const noexcept{
|
||||||
|
return m_info.sections;
|
||||||
|
}
|
||||||
|
bool sndrd::seekable()const noexcept{
|
||||||
|
return m_info.seekable;
|
||||||
|
}
|
||||||
|
|
||||||
|
error sndrd::last_error()const noexcept{
|
||||||
|
return error(sf_error(m_fp));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "audio/stream.hpp"
|
#include "audio/stream.hpp"
|
||||||
#include "audio/init.hpp"
|
#include "audio/init.hpp"
|
||||||
|
#include "audio/error.hpp"
|
||||||
|
|
||||||
#include <portaudio.h>
|
#include <portaudio.h>
|
||||||
|
|
||||||
@ -27,45 +28,45 @@ namespace audio{
|
|||||||
close();
|
close();
|
||||||
delete m_cb;
|
delete m_cb;
|
||||||
}
|
}
|
||||||
int stream::start(){
|
error stream::start(){
|
||||||
return m_err = Pa_StartStream(m_stream);
|
return error(m_err = Pa_StartStream(m_stream));
|
||||||
}
|
}
|
||||||
int stream::stop(){
|
error stream::stop(){
|
||||||
return m_err = Pa_StopStream(m_stream);
|
return error(m_err = Pa_StopStream(m_stream));
|
||||||
}
|
}
|
||||||
int stream::abort(){
|
error stream::abort(){
|
||||||
return m_err = Pa_AbortStream(m_stream);
|
return error(m_err = Pa_AbortStream(m_stream));
|
||||||
}
|
}
|
||||||
|
error stream::close(){
|
||||||
bool stream::is_stopped()const{
|
|
||||||
return Pa_IsStreamStopped(m_stream);
|
|
||||||
}
|
|
||||||
bool stream::is_active()const{
|
|
||||||
return Pa_IsStreamActive(m_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
int stream::close(){
|
|
||||||
if(m_stream){
|
if(m_stream){
|
||||||
m_err = Pa_CloseStream(m_stream);
|
m_err = Pa_CloseStream(m_stream);
|
||||||
m_stream = nullptr;
|
m_stream = nullptr;
|
||||||
return m_err;
|
return error(m_err);
|
||||||
}
|
}
|
||||||
return paNotInitialized;
|
return error(paNotInitialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream::last_error()const{
|
bool stream::is_stopped()const{
|
||||||
return m_err;
|
return (m_err = Pa_IsStreamStopped(m_stream)) == 1;
|
||||||
|
}
|
||||||
|
bool stream::is_active()const{
|
||||||
|
return (m_err = Pa_IsStreamActive(m_stream)) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
error stream::last_error()const{
|
||||||
|
return error(m_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
PaStream* stream::initialize_global_instance(){
|
PaStream* stream::initialize_global_instance(){
|
||||||
static pa_system sys;
|
pa_system::instance();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
int stream::open_default_stream(PaStream** stream, int in_c, int out_c,
|
int stream::open_default_stream(PaStream** stream, int in_c, int out_c,
|
||||||
stream_fmt fmt, double samplerate,
|
int fmt, double samplerate,
|
||||||
size_t bufsize, detail::callback_iface* cb)
|
size_t bufsize, detail::callback_iface* cb)
|
||||||
{
|
{
|
||||||
return Pa_OpenDefaultStream(stream, in_c, out_c, static_cast<int>(fmt), samplerate, bufsize, callback, cb);
|
return Pa_OpenDefaultStream(stream, in_c, out_c, fmt, samplerate, bufsize, callback, cb);
|
||||||
}
|
}
|
||||||
int stream::callback(const void* input, void* output, unsigned long framecount,
|
int stream::callback(const void* input, void* output, unsigned long framecount,
|
||||||
const PaStreamCallbackTimeInfo* /*timeInfo*/, PaStreamCallbackFlags /*statusFlags*/,
|
const PaStreamCallbackTimeInfo* /*timeInfo*/, PaStreamCallbackFlags /*statusFlags*/,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user