Commit 95982470 authored by David Reid's avatar David Reid

Remove old files and update examples.

parent ed22ebbf
......@@ -8,9 +8,9 @@ example (via libopus).
#define MA_NO_VORBIS /* Disable the built-in Vorbis decoder to ensure the libvorbis decoder is picked. */
#define MA_NO_OPUS /* Disable the (not yet implemented) built-in Opus decoder to ensure the libopus decoder is picked. */
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../../extras/miniaudio_libvorbis.h"
#include "../../extras/miniaudio_libopus.h"
#include "../miniaudio.h"
#include "../extras/miniaudio_libvorbis.h"
#include "../extras/miniaudio_libopus.h"
#include <stdio.h>
......
......@@ -7,9 +7,8 @@ the miniaudio repository. The vocoder node uses https://github.com/blastbay/vocl
effect.
*/
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../miniaudio_engine.h"
#include "../_extras/nodes/ma_vocoder_node/ma_vocoder_node.c"
#include "../miniaudio.h"
#include "../extras/nodes/ma_vocoder_node/ma_vocoder_node.c"
#include <stdio.h>
......
......@@ -14,8 +14,7 @@ If you were wanting to support multiple listeners, this example will show you ho
initializing one `ma_engine` object for each listener, each of which share a single self-managed resource manager.
*/
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../miniaudio_engine.h"
#include "../miniaudio.h"
#define MAX_DEVICES 2
#define MAX_SOUNDS 32
......
......@@ -25,8 +25,7 @@ set, each sound will have their own formats and you'll need to do the necessary
*/
#define MA_NO_ENGINE /* We're intentionally not using the ma_engine API here. */
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../miniaudio_engine.h"
#include "../miniaudio.h"
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
......
......@@ -16,8 +16,7 @@ threads to manage internally and how to implement your own custom job thread.
*/
#define MA_NO_ENGINE /* We're intentionally not using the ma_engine API here. */
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../miniaudio_engine.h"
#include "../miniaudio.h"
static ma_resource_manager_data_source g_dataSources[16];
static ma_uint32 g_dataSourceCount;
......
#define MINIAUDIO_IMPLEMENTATION
#include "../../../../miniaudio.h"
#include "../../../miniaudio_engine.h"
#include "../../../miniaudio.h"
#include "ma_channel_separator_node.c"
#include "../ma_channel_combiner_node/ma_channel_combiner_node.c"
......
#define MINIAUDIO_IMPLEMENTATION
#include "../../../../miniaudio.h"
#include "../../../miniaudio_engine.h"
#include "../../../miniaudio.h"
#include <stdio.h>
......
#define MINIAUDIO_IMPLEMENTATION
#include "../../../../miniaudio.h"
#include "../../../miniaudio_engine.h"
#include "../../../miniaudio.h"
#include "ma_reverb_node.c"
#include <stdio.h>
......
......@@ -7,8 +7,7 @@ the miniaudio repository. The vocoder node uses https://github.com/blastbay/vocl
effect.
*/
#define MINIAUDIO_IMPLEMENTATION
#include "../../../../miniaudio.h"
#include "../../../miniaudio_engine.h"
#include "../../../miniaudio.h"
#include "ma_vocoder_node.c"
#include <stdio.h>
......
#include "../../examples/custom_decoder_engine.c"
\ No newline at end of file
#include "../../examples/duplex_effect.c"
\ No newline at end of file
#include "../../examples/engine_hello_world.c"
\ No newline at end of file
#include "../../examples/resource_manager.c"
\ No newline at end of file
#include "../../examples/resource_manager_advanced.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_channel_combiner_node/ma_channel_combiner_node.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_channel_combiner_node/ma_channel_combiner_node.h"
\ No newline at end of file
#include "../../../../extras/nodes/ma_channel_combiner_node/ma_channel_combiner_node_example.c"
#include "../../../../extras/nodes/ma_channel_separator_node/ma_channel_separator_node.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_channel_separator_node/ma_channel_separator_node.h"
\ No newline at end of file
#include "../../../../extras/nodes/ma_channel_separator_node/ma_channel_separator_node_example.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_delay_node/ma_delay_node_example.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_reverb_node/ma_reverb_node.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_reverb_node/ma_reverb_node.h"
\ No newline at end of file
#include "../../../../extras/nodes/ma_reverb_node/ma_reverb_node_example.c"
\ No newline at end of file
This diff is collapsed.
#include "../../../../extras/nodes/ma_vocoder_node/ma_vocoder_node.c"
\ No newline at end of file
#include "../../../../extras/nodes/ma_vocoder_node/ma_vocoder_node.h"
\ No newline at end of file
#include "../../../../extras/nodes/ma_vocoder_node/ma_vocoder_node_example.c"
\ No newline at end of file
This diff is collapsed.
#define STB_VORBIS_HEADER_ONLY
#include "../extras/stb_vorbis.c" /* Enables Vorbis decoding. */
#define MA_EXPERIMENTAL__DATA_LOOPING_AND_CHAINING
#define MA_DEBUG_OUTPUT
#define MA_IMPLEMENTATION
#include "../miniaudio.h"
#include "miniaudio_engine.h"
typedef struct
{
ma_async_notification_callbacks cb;
ma_sound* pSound;
} sound_loaded_notification;
void on_sound_loaded(ma_async_notification* pNotification)
{
//sound_loaded_notification* pLoadedNotification = (sound_loaded_notification*)pNotification;
//ma_uint64 lengthInPCMFrames;
(void)pNotification;
/*
This will be fired when the sound has finished loading. We should be able to retrieve the length of the sound at this point. Here we'll just set
the fade out time.
*/
//ma_sound_get_length_in_pcm_frames(pLoadedNotification->pSound, &lengthInPCMFrames);
//ma_sound_set_fade_point_in_frames(pLoadedNotification->pSound, 1, 1, 0, lengthInPCMFrames - 192000, lengthInPCMFrames);
}
int main(int argc, char** argv)
{
ma_result result;
ma_resource_manager resourceManager;
ma_resource_manager_config resourceManagerConfig;
ma_engine engine;
ma_engine_config engineConfig;
ma_sound baseSound;
ma_sound sound;
ma_sound sound2;
sound_loaded_notification loadNotification;
ma_sound_group group;
if (argc < 2) {
printf("No input file.\n");
return -1;
}
resourceManagerConfig = ma_resource_manager_config_init();
//resourceManagerConfig.decodedFormat = ma_format_f32;
//resourceManagerConfig.decodedChannels = 2;
resourceManagerConfig.decodedSampleRate = 48000;
//resourceManagerConfig.flags |= MA_RESOURCE_MANAGER_FLAG_NO_THREADING;
resourceManagerConfig.jobThreadCount = 1;
resourceManagerConfig.jobQueueCapacity = 8;
result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager);
if (result != MA_SUCCESS) {
printf("Failed to initialize resource manager.\n");
return -1;
}
engineConfig = ma_engine_config_init();
engineConfig.pResourceManager = &resourceManager;
result = ma_engine_init(&engineConfig, &engine);
if (result != MA_SUCCESS) {
printf("Failed to initialize audio engine.\n");
return -1;
}
result = ma_sound_group_init(&engine, 0, NULL, &group);
if (result != MA_SUCCESS) {
printf("Failed to initialize sound group.");
return -1;
}
#if 1
loadNotification.cb.onSignal = on_sound_loaded;
loadNotification.pSound = &sound;
ma_sound_config soundConfig = ma_sound_config_init();
soundConfig.pFilePath = argv[1];
soundConfig.flags = MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM;
soundConfig.pInitialAttachment = &group;
soundConfig.loopPointBegInPCMFrames = 0;
soundConfig.loopPointEndInPCMFrames = 48000;
soundConfig.isLooping = MA_TRUE;
result = ma_sound_init_ex(&engine, &soundConfig, &sound);
if (result != MA_SUCCESS) {
printf("Failed to load sound: %s\n", argv[1]);
ma_engine_uninit(&engine);
return -1;
}
/*result = ma_sound_init_copy(&engine, &baseSound, 0, &group, &sound);
if (result != MA_SUCCESS) {
printf("Failed to copy sound.\n");
return -1;
}*/
#if 0
result = ma_sound_init_from_file(&engine, argv[1], MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE /*| MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC | MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM*/, NULL, &sound2);
if (result != MA_SUCCESS) {
printf("Failed to load sound: %s\n", argv[1]);
ma_engine_uninit(&engine);
return -1;
}
#endif
/*ma_data_source_seek_to_pcm_frame(sound.pDataSource, 5000000);*/
//ma_sound_group_set_pan(ma_engine_get_master_sound_group(&engine), -1);
ma_sound_group_set_pitch(&group, 1.5f);
//ma_sound_group_set_start_time(ma_engine_get_master_sound_group(&engine), 2000);
//ma_sound_group_set_fade_in_milliseconds(&group, 0, 1, 5000);
//ma_sound_group_stop(&group);
//ma_engine_listener_set_enabled(&engine, 0, MA_FALSE);
//ma_sound_set_fade_in_milliseconds(&sound, 0, 1, 5000);
/*ma_sound_set_volume(&sound, 0.25f);*/
/*ma_sound_set_pitch(&sound, 1.1f);*/
/*ma_sound_set_pan(&sound, 0.0f);*/
ma_sound_set_looping(&sound, MA_TRUE);
//ma_data_source_set_range_in_pcm_frames(ma_sound_get_data_source(&sound), 0, 48000);
//ma_data_source_set_loop_point_in_pcm_frames(ma_sound_get_data_source(&sound), 0, 48000);
//ma_sound_seek_to_pcm_frame(&sound, 6000000);
//ma_sound_set_start_time(&sound, 1110);
//ma_sound_set_volume(&sound, 0.5f);
//ma_sound_set_fade_point_in_milliseconds(&sound, 0, 0, 1, 0, 2000);
//ma_sound_set_fade_point_auto_reset(&sound, 0, MA_FALSE); /* Enable fading around loop transitions. */
//ma_sound_set_fade_point_auto_reset(&sound, 1, MA_FALSE);
//ma_sound_set_stop_time(&sound, 1000);
//ma_sound_set_volume(&sound, 1);
//ma_sound_set_start_time(&sound, 48000);
ma_sound_set_position(&sound, 0, 0, -1);
//ma_sound_set_spatialization_enabled(&sound, MA_FALSE);
ma_sound_start(&sound);
/*ma_sound_uninit(&sound);*/
//ma_sleep(1000);
//ma_sound_set_looping(&sound2, MA_TRUE);
//ma_sound_set_volume(&sound2, 0.5f);
//ma_sound_start(&sound2);
//ma_sleep(2000);
//printf("Stopping...\n");
//ma_sound_stop(&sound);
//ma_sound_group_stop(ma_engine_get_master_sound_group(&engine));
#endif
#if 1
/*ma_engine_play_sound(&engine, argv[1], NULL);*/
/*ma_engine_play_sound(&engine, argv[2], NULL);
ma_engine_play_sound(&engine, argv[3], NULL);*/
#endif
#if 0
for (;;) {
ma_resource_manager_process_next_job(&resourceManager);
ma_sleep(5);
}
#endif
#if 1
float maxX = +1;
float minX = -1;
float posX = 0;
float posZ = -1.0f;
float step = 0.1f;
float stepAngle = 0.02f;
float angle = 0;
float pitch = 1;
float pitchStep = 0.01f;
float pitchMin = 0.125f;
float pitchMax = 2;
for (;;) {
pitch += pitchStep;
if (pitch < pitchMin) {
pitch = pitchMin;
pitchStep = -pitchStep;
}
if (pitch > pitchMax) {
pitch = pitchMax;
pitchStep = -pitchStep;
}
//ma_sound_group_set_pitch(ma_engine_get_master_sound_group(&engine), pitch);
//ma_sound_set_pitch(&sound, pitch);
//ma_sound_set_volume(&sound, pitch);
//ma_sound_set_pan(&sound, pitch);
//printf("Pitch: %f\n", pitch);
posX += step;
if (posX > maxX) {
posX = maxX;
step = -step;
} else if (posX < minX) {
posX = minX;
step = -step;
}
//ma_spatializer_set_position(&g_spatializer, ma_vec3f_init_3f(posX, 0, posZ));
ma_sound_set_position(&sound, 0, 0, -2);
ma_engine_listener_set_position(&engine, 0, 0, 0, -10);
ma_engine_listener_set_direction(&engine, 0, -1, 0, 0);
//ma_sound_set_velocity(&sound, step*1000, 0, 0);
ma_engine_listener_set_direction(&engine, 0, (float)ma_cosd(angle), 0, (float)ma_sind(angle));
angle += stepAngle;
ma_sleep(1);
}
#endif
printf("Press Enter to quit...");
getchar();
ma_sound_uninit(&sound);
ma_engine_uninit(&engine);
return 0;
}
/* stb_vorbis implementation must come after the implementation of miniaudio. */
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
#pragma warning(disable:4100) /* unreferenced formal parameter */
#pragma warning(disable:4244) /* '=': conversion from '' to '', possible loss of data */
#pragma warning(disable:4245) /* '=': conversion from '' to '', signed/unsigned mismatch */
#pragma warning(disable:4456) /* declaration of '' hides previous local declaration */
#pragma warning(disable:4457) /* declaration of '' hides function parameter */
#pragma warning(disable:4701) /* potentially uninitialized local variable '' used */
#else
#endif
#undef STB_VORBIS_HEADER_ONLY
#include "../extras/stb_vorbis.c"
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(pop)
#else
#endif
/* !!! THIS FILE WILL BE MERGED INTO miniaudio.h WHEN COMPLETE !!! */
/*
EXPERIMENTAL
============
Everything in this file is experimental and subject to change. Some stuff isn't yet implemented, in particular spatialization. I've noted some ideas that are
basically straight off the top of my head - many of these are probably outright wrong or just generally bad ideas.
Very simple APIs for spatialization are declared by not yet implemented. They're just placeholders to give myself an idea on some of the API design.
The idea is that you have an `ma_engine` object - one per listener. Decoupled from that is the `ma_resource_manager` object. You can have one `ma_resource_manager`
object to many `ma_engine` objects. This will allow you to share resources between each listener. The `ma_engine` is responsible for the playback of audio from a
list of data sources. The `ma_resource_manager` is responsible for the actual loading, caching and unloading of those data sources. This decoupling is
something that I'm really liking right now and will likely stay in place for the final version.
You create "sounds" from the engine which represent a sound/voice in the world. You first need to create a sound, and then you need to start it. Sounds do not
start by default. You can use `ma_engine_play_sound()` to "fire and forget" sounds.
Sounds can be allocated to groups called `ma_sound_group`. This is how you can support submixing and is one way you could achieve the kinds of groupings you see
in games for things like SFX, Music and Voices. Unlike sounds, groups are started by default. When you stop a group, all sounds within that group will be
stopped atomically. When the group is started again, all sounds attached to the group will also be started, so long as the sound is also marked as started.
The creation and deletion of sounds and groups should be thread safe.
The engine runs on top of a node graph, and sounds and groups are just nodes within that graph. The output of a sound can be attached to the input of any node
on the graph. To apply an effect to a sound or group, attach it's output to the input of an effect node. See the Routing Infrastructure section below for
details on this.
The best resource to use when understanding the API is the function declarations for `ma_engine`. I expect you should be able to figure it out! :)
*/
#ifndef miniaudio_engine_h
#define miniaudio_engine_h
#ifdef __cplusplus
extern "C" {
#endif
/*
Engine
======
The `ma_engine` API is a high-level API for audio playback. Internally it contains sounds (`ma_sound`) with resources managed via a resource manager
(`ma_resource_manager`).
Within the world there is the concept of a "listener". Each `ma_engine` instances has a single listener, but you can instantiate multiple `ma_engine` instances
if you need more than one listener. In this case you will want to share a resource manager which you can do by initializing one manually and passing it into
`ma_engine_config`. Using this method will require your application to manage groups and sounds on a per `ma_engine` basis.
*/
#ifdef __cplusplus
}
#endif
#endif /* miniaudio_engine_h */
#if defined(MA_IMPLEMENTATION) || defined(MINIAUDIO_IMPLEMENTATION)
#endif
#define MINIAUDIO_IMPLEMENTATION
#include "../miniaudio.h"
#include "miniaudio_engine.h"
ma_node_graph g_nodeGraph;
ma_data_source_node g_dataSourceNode;
ma_splitter_node g_splitterNode;
ma_splitter_node g_loopNode; /* For testing loop detection. We're going to route one of these endpoints back to g_splitterNode to form a loop. */
void data_callback(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount)
{
/* Read straight from our node graph. */
ma_node_graph_read_pcm_frames(&g_nodeGraph, pFramesOut, frameCount, NULL);
(void)pDevice; /* Unused. */
(void)pFramesIn; /* Unused. */
}
int main(int argc, char** argv)
{
ma_result result;
ma_device_config deviceConfig;
ma_device device;
ma_decoder_config decoderConfig;
ma_decoder decoder;
ma_node_graph_config nodeGraphConfig;
ma_data_source_node_config dataSourceNodeConfig;
ma_splitter_node_config splitterNodeConfig;
if (argc <= 1) {
printf("No input file.");
return -1;
}
deviceConfig = ma_device_config_init(ma_device_type_playback);
deviceConfig.playback.format = ma_format_f32; /* The node graph API only supports f32. */
deviceConfig.playback.channels = 2;
deviceConfig.sampleRate = 48000;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = NULL;
result = ma_device_init(NULL, &deviceConfig, &device);
if (result != MA_SUCCESS) {
printf("Failed to initialize device.");
return -1;
}
/*
Set up the new graph before starting the device so that we have something to read from as soon
as the device requests data. It doesn't matter what order we do this, but I'm starting with the
data source node since it makes more logical sense to me to start with the start of the chain.
*/
nodeGraphConfig = ma_node_graph_config_init(device.playback.channels);
result = ma_node_graph_init(&nodeGraphConfig, NULL, &g_nodeGraph);
if (result != MA_SUCCESS) {
printf("Failed to initialize node graph.");
return -1;
}
/*
We want the decoder to use the same format as the device. This way we can keep the entire node
graph using the same format/channels/rate to avoid the need to do data conversion.
*/
decoderConfig = ma_decoder_config_init(device.playback.format, device.playback.channels, device.sampleRate);
result = ma_decoder_init_file(argv[1], &decoderConfig, &decoder);
if (result != MA_SUCCESS) {
printf("Failed to initialize decoder.");
ma_device_uninit(&device);
return -1;
}
dataSourceNodeConfig = ma_data_source_node_config_init(&decoder, MA_TRUE);
result = ma_data_source_node_init(&g_nodeGraph, &dataSourceNodeConfig, NULL, &g_dataSourceNode);
if (result != MA_SUCCESS) {
printf("Failed to initialize data source node.");
ma_decoder_uninit(&decoder);
ma_device_uninit(&device);
return -1;
}
/*result = ma_node_attach_output_bus(&g_dataSourceNode, 0, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
if (result != MA_SUCCESS) {
printf("Failed to attach node.");
return -1;
}*/
/*ma_node_set_state_time(&g_dataSourceNode, ma_node_state_started, 48000*1);
ma_node_set_state_time(&g_dataSourceNode, ma_node_state_stopped, 48000*5);*/
#if 1
/*
Splitter node. Note that we've already attached the data source node to another, so this section
will test that changing of attachments works as expected.
*/
splitterNodeConfig = ma_splitter_node_config_init(device.playback.channels);
/* Loop detection testing. */
result = ma_splitter_node_init(&g_nodeGraph, &splitterNodeConfig, NULL, &g_loopNode);
if (result != MA_SUCCESS) {
printf("Failed to initialize loop node.");
return -1;
}
/* Adjust the volume of the splitter node's endpoints. We'll just do it 50/50 so that both of them combine to reproduce the original signal at the endpoint. */
ma_node_set_output_bus_volume(&g_loopNode, 0, 1.0f);
ma_node_set_output_bus_volume(&g_loopNode, 1, 1.0f);
result = ma_splitter_node_init(&g_nodeGraph, &splitterNodeConfig, NULL, &g_splitterNode);
if (result != MA_SUCCESS) {
printf("Failed to initialize splitter node.");
return -1;
}
#if 0
/* Connect both outputs of the splitter to the endpoint for now. Later on we'll test effects and whatnot. */
ma_node_attach_output_bus(&g_splitterNode, 0, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
ma_node_attach_output_bus(&g_splitterNode, 1, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
/* Adjust the volume of the splitter node's endpoints. We'll just do it 50/50 so that both of them combine to reproduce the original signal at the endpoint. */
ma_node_set_output_bus_volume(&g_splitterNode, 0, 0.5f);
ma_node_set_output_bus_volume(&g_splitterNode, 1, 0.5f);
/* The data source needs to have it's connection changed from the endpoint to the splitter. */
ma_node_attach_output_bus(&g_dataSourceNode, 0, &g_splitterNode, 0);
#else
/* Connect the loop node directly to the output. */
ma_node_attach_output_bus(&g_loopNode, 0, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
ma_node_attach_output_bus(&g_loopNode, 1, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
/* Connect the splitter node directly to the loop node. */
ma_node_attach_output_bus(&g_splitterNode, 0, &g_loopNode, 0);
ma_node_attach_output_bus(&g_splitterNode, 1, &g_loopNode, 1);
/* Connect the data source node to the splitter node. */
ma_node_attach_output_bus(&g_dataSourceNode, 0, &g_splitterNode, 0);
/* Now loop back to the splitter node to form a loop. */
ma_node_attach_output_bus(&g_loopNode, 1, &g_splitterNode, 0);
#endif
#endif
/* Stop the splitter node for testing. */
/*ma_node_set_state(&g_splitterNode, ma_node_state_stopped);*/
/*
Only start the device after our nodes have been set up. We passed in `deviceNode` as the user
data to the data callback so we need to make sure it's initialized before we start the device.
*/
result = ma_device_start(&device);
if (result != MA_SUCCESS) {
ma_device_uninit(&device);
return -1;
}
printf("Press Enter to quit...");
getchar();
/* Teardown. These are uninitialized in a weird order here just for demonstration. */
/* We should be able to safely destroy the node while the device is still running. */
ma_data_source_node_uninit(&g_dataSourceNode, NULL);
/* The device needs to be stopped before we uninitialize the node graph or else the device's callback will try referencing the node graph. */
ma_device_uninit(&device);
/* The node graph will be referenced by the device's data called so it needs to be uninitialized after the device has stopped. */
ma_node_graph_uninit(&g_nodeGraph, NULL);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment