switched to miniaudio since libsoundio is unmantained
This commit is contained in:
parent
dc0b7e94b4
commit
4a798951c3
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "extern/libsoundio"]
|
||||
path = extern/libsoundio
|
||||
url = https://github.com/andrewrk/libsoundio.git
|
||||
@ -9,25 +9,30 @@ set(C_STANDARD_REQUIRED True)
|
||||
|
||||
add_executable(${PROJECT_NAME} src/main.c)
|
||||
|
||||
# TODO: set with if checks
|
||||
set(ENABLE_ALSA ON CACHE BOOL "")
|
||||
set(ENABLE_PULSEAUDIO OFF CACHE BOOL "")
|
||||
set(ENABLE_JACK OFF CACHE BOOL "")
|
||||
set(ENABLE_COREAUDIO OFF CACHE BOOL "")
|
||||
set(ENABLE_WASAPI OFF CACHE BOOL "")
|
||||
set(BUILD_EXAMPLE_PROGRAMS OFF CACHE BOOL "")
|
||||
# Pull all submodules if haven't already
|
||||
# find_package(Git QUIET)
|
||||
# if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
# option(GIT_SUBMODULE "Check submodules during build" ON)
|
||||
# if(GIT_SUBMODULE)
|
||||
# message(STATUS "Submodule update")
|
||||
# execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
# RESULT_VARIABLE GIT_SUBMOD_RESULT)
|
||||
# if(NOT GIT_SUBMOD_RESULT EQUAL "0")
|
||||
# message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
|
||||
# endif()
|
||||
# endif()
|
||||
# endif()
|
||||
#
|
||||
# if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/libsoundio/CMakeLists.txt")
|
||||
# message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
|
||||
# endif()
|
||||
|
||||
set(BUILD_DYNAMIC_LIBS ON CACHE BOOL "" FORCE)
|
||||
set(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
||||
|
||||
# libsoundio
|
||||
add_subdirectory("${CMAKE_SOURCE_DIR}/extern/libsoundio")
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/extern/libsoundio")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:libsoundio_shared>
|
||||
$<$<CONFIG:Release>:libsoundio_static>
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/extern/miniaudio")
|
||||
|
||||
# math
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE m)
|
||||
|
||||
1
extern/libsoundio
vendored
1
extern/libsoundio
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 49a1f78b50eb0f5a49d096786a95a93874a2592a
|
||||
95649
extern/miniaudio/miniaudio.h
vendored
Normal file
95649
extern/miniaudio/miniaudio.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
155
src/main.c
155
src/main.c
@ -1,108 +1,95 @@
|
||||
#include <soundio/soundio.h>
|
||||
// beep.c
|
||||
// Build (Linux/macOS): cc beep.c -lm -o beep
|
||||
// Build (Windows MSVC): cl /O2 beep.c
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const float PI = 3.1415926535f;
|
||||
static float seconds_offset = 0.0f;
|
||||
static void write_callback(struct SoundIoOutStream *outstream,
|
||||
int frame_count_min, int frame_count_max)
|
||||
typedef struct {
|
||||
double phase;
|
||||
double phase_inc;
|
||||
uint32_t frames_left;
|
||||
ma_uint32 channels;
|
||||
} beep_state;
|
||||
|
||||
static void data_callback(ma_device* dev, void* out, const void* in, ma_uint32 frameCount)
|
||||
{
|
||||
const struct SoundIoChannelLayout *layout = &outstream->layout;
|
||||
float float_sample_rate = outstream->sample_rate;
|
||||
float seconds_per_frame = 1.0f / float_sample_rate;
|
||||
struct SoundIoChannelArea *areas;
|
||||
int frames_left = frame_count_max;
|
||||
int err;
|
||||
(void)in;
|
||||
beep_state* s = (beep_state*)dev->pUserData;
|
||||
float* output = (float*)out;
|
||||
|
||||
while (frames_left > 0) {
|
||||
int frame_count = frames_left;
|
||||
ma_uint32 framesToWrite = frameCount;
|
||||
if (s->frames_left < framesToWrite) framesToWrite = s->frames_left;
|
||||
|
||||
if ((err = soundio_outstream_begin_write(outstream, &areas, &frame_count))) {
|
||||
fprintf(stderr, "%s\n", soundio_strerror(err));
|
||||
exit(1);
|
||||
for (ma_uint32 i = 0; i < framesToWrite; i++) {
|
||||
float sample = (float)sin(s->phase) * 0.2f; // volume
|
||||
s->phase += s->phase_inc;
|
||||
|
||||
// keep phase bounded (optional)
|
||||
if (s->phase >= (2.0 * M_PI)) s->phase -= (2.0 * M_PI);
|
||||
|
||||
for (ma_uint32 ch = 0; ch < s->channels; ch++) {
|
||||
output[i * s->channels + ch] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
if (!frame_count)
|
||||
break;
|
||||
|
||||
float pitch = 440.0f;
|
||||
float radians_per_second = pitch * 2.0f * PI;
|
||||
for (int frame = 0; frame < frame_count; frame += 1) {
|
||||
float sample = sin((seconds_offset + frame * seconds_per_frame) * radians_per_second);
|
||||
for (int channel = 0; channel < layout->channel_count; channel += 1) {
|
||||
float *ptr = (float*)(areas[channel].ptr + areas[channel].step * frame);
|
||||
*ptr = sample;
|
||||
}
|
||||
// If we ran out early, zero the rest (silence).
|
||||
for (ma_uint32 i = framesToWrite; i < frameCount; i++) {
|
||||
for (ma_uint32 ch = 0; ch < s->channels; ch++) {
|
||||
output[i * s->channels + ch] = 0.0f;
|
||||
}
|
||||
seconds_offset = fmod(seconds_offset + seconds_per_frame * frame_count, 1.0);
|
||||
}
|
||||
|
||||
if ((err = soundio_outstream_end_write(outstream))) {
|
||||
fprintf(stderr, "%s\n", soundio_strerror(err));
|
||||
exit(1);
|
||||
}
|
||||
s->frames_left -= framesToWrite;
|
||||
|
||||
frames_left -= frame_count;
|
||||
// Stop after the beep finishes.
|
||||
if (s->frames_left == 0) {
|
||||
ma_device_stop(dev); // safe to request stop
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int err;
|
||||
struct SoundIo *soundio = soundio_create();
|
||||
if (!soundio) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
int main(void)
|
||||
{
|
||||
const double freq = 440.0;
|
||||
const ma_uint32 sampleRate = 48000;
|
||||
const double durationSec = 1.0;
|
||||
|
||||
beep_state s = {0};
|
||||
s.phase = 0.0;
|
||||
s.phase_inc = (2.0 * M_PI * freq) / (double)sampleRate;
|
||||
s.frames_left = (uint32_t)(durationSec * (double)sampleRate);
|
||||
|
||||
ma_device_config cfg = ma_device_config_init(ma_device_type_playback);
|
||||
cfg.playback.format = ma_format_f32;
|
||||
cfg.playback.channels = 2;
|
||||
cfg.sampleRate = sampleRate;
|
||||
cfg.dataCallback = data_callback;
|
||||
cfg.pUserData = &s;
|
||||
|
||||
ma_device dev;
|
||||
if (ma_device_init(NULL, &cfg, &dev) != MA_SUCCESS) {
|
||||
fprintf(stderr, "Failed to init audio device\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((err = soundio_connect(soundio))) {
|
||||
fprintf(stderr, "error connecting: %s\n", soundio_strerror(err));
|
||||
s.channels = dev.playback.channels; // in case backend adjusts
|
||||
|
||||
if (ma_device_start(&dev) != MA_SUCCESS) {
|
||||
fprintf(stderr, "Failed to start audio device\n");
|
||||
ma_device_uninit(&dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
soundio_flush_events(soundio);
|
||||
|
||||
int default_out_device_index = soundio_default_output_device_index(soundio);
|
||||
if (default_out_device_index < 0) {
|
||||
fprintf(stderr, "no output device found\n");
|
||||
return 1;
|
||||
// Wait until callback stops the device.
|
||||
while (ma_device_is_started(&dev)) {
|
||||
ma_sleep(10);
|
||||
}
|
||||
|
||||
struct SoundIoDevice *device = soundio_get_output_device(soundio, default_out_device_index);
|
||||
if (!device) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Output device: %s\n", device->name);
|
||||
|
||||
struct SoundIoOutStream *outstream = soundio_outstream_create(device);
|
||||
if (!outstream) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
outstream->format = SoundIoFormatFloat32NE;
|
||||
outstream->write_callback = write_callback;
|
||||
|
||||
if ((err = soundio_outstream_open(outstream))) {
|
||||
fprintf(stderr, "unable to open device: %s", soundio_strerror(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (outstream->layout_error)
|
||||
fprintf(stderr, "unable to set channel layout: %s\n", soundio_strerror(outstream->layout_error));
|
||||
|
||||
if ((err = soundio_outstream_start(outstream))) {
|
||||
fprintf(stderr, "unable to start device: %s\n", soundio_strerror(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
soundio_wait_events(soundio);
|
||||
|
||||
soundio_outstream_destroy(outstream);
|
||||
soundio_device_unref(device);
|
||||
soundio_destroy(soundio);
|
||||
ma_device_uninit(&dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user