Audio file simplifications, add a couple debug utilities
This commit is contained in:
parent
a71c3c27c4
commit
1987f3b9fa
@ -46,6 +46,7 @@ namespace audio{
|
|||||||
|
|
||||||
void resize_buffer(size_t newsize);
|
void resize_buffer(size_t newsize);
|
||||||
|
|
||||||
|
void play(const mixchunk& m);
|
||||||
void play(const mixdata& m);
|
void play(const mixdata& m);
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
|
|||||||
@ -24,11 +24,44 @@
|
|||||||
namespace audio{
|
namespace audio{
|
||||||
|
|
||||||
struct mixdata {
|
struct mixdata {
|
||||||
float* data;
|
float* data = nullptr;
|
||||||
size_t frames;
|
size_t frames = 0;
|
||||||
size_t channels;
|
size_t channels = 0;
|
||||||
size_t samplerate;
|
size_t samplerate = 0;
|
||||||
float volume = 1;
|
float volume = 1;
|
||||||
|
bool allocated = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
class mixchunk
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
mixdata m_data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr mixchunk() = default;
|
||||||
|
mixchunk(size_t frames, size_t channels, size_t samplerate);
|
||||||
|
mixchunk(const mixdata&);
|
||||||
|
mixchunk(mixdata&&);
|
||||||
|
mixchunk(const mixchunk&);
|
||||||
|
mixchunk(mixchunk&&);
|
||||||
|
~mixchunk();
|
||||||
|
|
||||||
|
mixchunk& operator=(const mixchunk&);
|
||||||
|
mixchunk& operator=(mixchunk&&);
|
||||||
|
|
||||||
|
const float* data()const;
|
||||||
|
float* data();
|
||||||
|
|
||||||
|
size_t floats()const;
|
||||||
|
size_t frames()const;
|
||||||
|
size_t channels()const;
|
||||||
|
size_t samplerate()const;
|
||||||
|
float volume()const;
|
||||||
|
|
||||||
|
void set_samplerate(size_t s);
|
||||||
|
void set_volume(float v);
|
||||||
|
|
||||||
|
const mixdata& raw()const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ namespace audio{
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class mode : int{
|
enum class mode : int{
|
||||||
|
MONO = 1,
|
||||||
STEREO = 2,
|
STEREO = 2,
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
#include "mixdata.hpp"
|
||||||
|
|
||||||
namespace audio{
|
namespace audio{
|
||||||
|
|
||||||
@ -64,7 +65,10 @@ namespace audio{
|
|||||||
const SNDFILE* get(void)const noexcept;
|
const SNDFILE* get(void)const noexcept;
|
||||||
bool valid()const noexcept;
|
bool valid()const noexcept;
|
||||||
|
|
||||||
|
mixchunk read_all()noexcept;
|
||||||
|
mixchunk read(size_t items)noexcept;
|
||||||
size_t read(float* dest, size_t items)noexcept;
|
size_t read(float* dest, size_t items)noexcept;
|
||||||
|
mixchunk read_frames(size_t frames)noexcept;
|
||||||
size_t read_frames(float* dest, size_t frames)noexcept;
|
size_t read_frames(float* dest, size_t frames)noexcept;
|
||||||
//TODO other formats
|
//TODO other formats
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
#ifndef OUR_DICK_CONFIG_HPP
|
#ifndef OUR_DICK_CONFIG_HPP
|
||||||
#define OUR_DICK_CONFIG_HPP
|
#define OUR_DICK_CONFIG_HPP
|
||||||
|
|
||||||
|
//multiple levels just so i can stop alsa errors without stopping everything else
|
||||||
|
#define OUR_DICK_DEBUG 1
|
||||||
|
|
||||||
|
#ifdef OUR_DICK_DEBUG
|
||||||
|
#include <cstdio>
|
||||||
|
#define debug_print(...) fprintf(stderr, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define debug_print(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -25,6 +25,9 @@ namespace audio{
|
|||||||
channel::channel(impl::channel& c):
|
channel::channel(impl::channel& c):
|
||||||
m_impl(&c){}
|
m_impl(&c){}
|
||||||
|
|
||||||
|
void channel::play(const mixchunk& m){
|
||||||
|
m_impl->play(m.raw());
|
||||||
|
}
|
||||||
void channel::play(const mixdata& m){
|
void channel::play(const mixdata& m){
|
||||||
m_impl->play(m);
|
m_impl->play(m);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,21 +17,28 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "audio/init.hpp"
|
#include "audio/init.hpp"
|
||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
#include <portaudio.h>
|
#include <portaudio.h>
|
||||||
|
|
||||||
#ifdef __gnu_linux__
|
#if defined(__gnu_linux__)
|
||||||
|
#if !defined(OUR_DICK_DEBUG) || OUR_DICK_DEBUG <= 1
|
||||||
|
#define ENABLE_ALSA_DEBUG
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_ALSA_DEBUG
|
||||||
#include <cstdarg> //va_arg (missing include in alsa headers)
|
#include <cstdarg> //va_arg (missing include in alsa headers)
|
||||||
#include <alsa/error.h> //snd_lib_error_set_handler
|
#include <alsa/error.h> //snd_lib_error_set_handler
|
||||||
namespace audio::detail{
|
namespace audio::detail{
|
||||||
void linux_alsa_error_handler(const char* /*file*/, int /*line*/, const char* /*function*/, int /*err*/, const char* /*fmt*/,...){}
|
static void linux_alsa_error_handler(const char* /*file*/, int /*line*/, const char* /*function*/, int /*err*/, const char* /*fmt*/,...){}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace audio{
|
namespace audio{
|
||||||
|
|
||||||
pa_system::pa_system(){
|
pa_system::pa_system(){
|
||||||
#ifdef __gnu_linux__
|
#ifdef ENABLE_ALSA_DEBUG
|
||||||
//silence excessive stderr warnings from alsa
|
//silence excessive stderr warnings from alsa
|
||||||
snd_lib_error_set_handler(detail::linux_alsa_error_handler);
|
snd_lib_error_set_handler(detail::linux_alsa_error_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
103
src/audio/mixdata.cpp
Normal file
103
src/audio/mixdata.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
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/mixdata.hpp"
|
||||||
|
|
||||||
|
#include <utility> //exchange, swap, move
|
||||||
|
#include <cstring> //mpmcpy, memset
|
||||||
|
|
||||||
|
namespace audio{
|
||||||
|
|
||||||
|
mixchunk::mixchunk(size_t frames, size_t channels, size_t samplerate):
|
||||||
|
m_data{new float[frames * channels](), frames, channels, samplerate, 1, true}{}
|
||||||
|
mixchunk::mixchunk(const mixdata& m):
|
||||||
|
m_data{new float[m.frames * m.channels](), m.frames, m.channels, m.samplerate, m.volume, true}
|
||||||
|
{
|
||||||
|
memcpy(m_data.data, m.data, m_data.frames * m_data.channels);
|
||||||
|
}
|
||||||
|
mixchunk::mixchunk(mixdata&& m):
|
||||||
|
m_data{std::exchange(m.data, nullptr), m.frames, m.channels, m.samplerate, m.volume, m.allocated}{}
|
||||||
|
mixchunk::mixchunk(const mixchunk& m):
|
||||||
|
mixchunk(m.m_data){}
|
||||||
|
mixchunk::mixchunk(mixchunk&& m):
|
||||||
|
mixchunk(std::move(m.m_data)){}
|
||||||
|
mixchunk::~mixchunk(){
|
||||||
|
if(m_data.allocated)
|
||||||
|
delete[] m_data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
mixchunk& mixchunk::operator=(const mixchunk& m){
|
||||||
|
size_t this_floats = m_data.frames * m_data.channels;
|
||||||
|
size_t that_floats = m.m_data.frames * m.m_data.channels;
|
||||||
|
|
||||||
|
if(this_floats > that_floats){
|
||||||
|
memcpy(m_data.data, m.m_data.data, that_floats);
|
||||||
|
memset(m_data.data + that_floats, 0, this_floats - that_floats);
|
||||||
|
}else if(this_floats == that_floats){
|
||||||
|
memcpy(m_data.data, m.m_data.data, that_floats);
|
||||||
|
}else{
|
||||||
|
return (*this = mixchunk(m));
|
||||||
|
}
|
||||||
|
m_data.frames = m.m_data.frames;
|
||||||
|
m_data.channels = m.m_data.channels;
|
||||||
|
m_data.samplerate = m.m_data.samplerate;
|
||||||
|
m_data.volume = m.m_data.volume;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
mixchunk& mixchunk::operator=(mixchunk&& m){
|
||||||
|
std::swap(m_data.data, m.m_data.data);
|
||||||
|
std::swap(m_data.allocated, m.m_data.allocated);
|
||||||
|
m_data.frames = m.m_data.frames;
|
||||||
|
m_data.channels = m.m_data.channels;
|
||||||
|
m_data.samplerate = m.m_data.samplerate;
|
||||||
|
m_data.volume = m.m_data.volume;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
float* mixchunk::data(){
|
||||||
|
return m_data.data;
|
||||||
|
}
|
||||||
|
const float* mixchunk::data()const{
|
||||||
|
return m_data.data;
|
||||||
|
}
|
||||||
|
size_t mixchunk::floats()const{
|
||||||
|
return frames() * channels();
|
||||||
|
}
|
||||||
|
size_t mixchunk::frames()const{
|
||||||
|
return m_data.frames;
|
||||||
|
}
|
||||||
|
size_t mixchunk::channels()const{
|
||||||
|
return m_data.channels;
|
||||||
|
}
|
||||||
|
size_t mixchunk::samplerate()const{
|
||||||
|
return m_data.samplerate;
|
||||||
|
}
|
||||||
|
float mixchunk::volume()const{
|
||||||
|
return m_data.volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mixchunk::set_samplerate(size_t s){
|
||||||
|
m_data.samplerate = s;
|
||||||
|
}
|
||||||
|
void mixchunk::set_volume(float v){
|
||||||
|
m_data.volume = v;
|
||||||
|
}
|
||||||
|
const mixdata& mixchunk::raw()const{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -74,9 +74,20 @@ namespace audio{
|
|||||||
return m_fp && !last_error();
|
return m_fp && !last_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mixchunk sndrd::read_all()noexcept{
|
||||||
|
return read_frames(frames());
|
||||||
|
}
|
||||||
|
mixchunk sndrd::read(size_t items)noexcept{
|
||||||
|
return read_frames(items / channels());
|
||||||
|
}
|
||||||
size_t sndrd::read(float* dest, size_t items)noexcept{
|
size_t sndrd::read(float* dest, size_t items)noexcept{
|
||||||
return sf_read_float(m_fp, dest, items);
|
return sf_read_float(m_fp, dest, items);
|
||||||
}
|
}
|
||||||
|
mixchunk sndrd::read_frames(size_t fcnt)noexcept{
|
||||||
|
mixchunk c(fcnt, channels(), samplerate());
|
||||||
|
read_frames(c.data(), fcnt);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
size_t sndrd::read_frames(float* dest, size_t frames)noexcept{
|
size_t sndrd::read_frames(float* dest, size_t frames)noexcept{
|
||||||
return sf_readf_float(m_fp, dest, frames);
|
return sf_readf_float(m_fp, dest, frames);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "render.hpp"
|
#include "render.hpp"
|
||||||
#include "game_state.hpp"
|
#include "game_state.hpp"
|
||||||
#include "math/math.hpp"
|
#include "math/math.hpp"
|
||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
// 0 | 1 | 2
|
// 0 | 1 | 2
|
||||||
// ---------
|
// ---------
|
||||||
@ -89,12 +90,12 @@ void play_audio(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_window_close(){
|
void handle_window_close(){
|
||||||
printf("[II] Window close event triggered\n");
|
debug_print("[II] Window close event triggered\n");
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_input_events(GLFWwindow*, int key, int, int, int){
|
void handle_input_events(GLFWwindow*, int key, int, int, int){
|
||||||
printf("[II] Recieved keycode %d\n", key);
|
debug_print("[II] Recieved keycode %d\n", key);
|
||||||
if(key == 256)
|
if(key == 256)
|
||||||
manager.request_exit();
|
manager.request_exit();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
#include <gl3w/GL/gl3w.h> // Must be included first
|
#include <gl3w/GL/gl3w.h> // Must be included first
|
||||||
#include "render.hpp"
|
#include "render.hpp"
|
||||||
|
#include "config.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace{
|
namespace{
|
||||||
void handle_resize_event(GLFWwindow*, int width, int height){
|
void handle_resize_event(GLFWwindow*, int width, int height){
|
||||||
printf("Window resized\n");
|
debug_print("Window resized\n");
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +40,7 @@ render_manager::renderer_error render_manager::init (int width, int height, cons
|
|||||||
|
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
|
|
||||||
printf("[DD] OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
|
debug_print("[DD] OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
|
||||||
glfwSetFramebufferSizeCallback(m_main_window, handle_resize_event);
|
glfwSetFramebufferSizeCallback(m_main_window, handle_resize_event);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user