mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Remove loop detection code for now.
This needs a rethink. My test is no longer looping. Needs further investigation.
This commit is contained in:
@@ -65,20 +65,18 @@ int main(int argc, char** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
result = ma_sound_group_init(&engine, 0, NULL, &group);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize sound group.");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
loadNotification.cb.onSignal = on_sound_loaded;
|
||||
loadNotification.pSound = &sound;
|
||||
|
||||
result = ma_sound_init_from_file(&engine, argv[1], MA_DATA_SOURCE_FLAG_DECODE /*| MA_DATA_SOURCE_FLAG_ASYNC | MA_DATA_SOURCE_FLAG_STREAM*/, &loadNotification, NULL, &sound);
|
||||
result = ma_sound_init_from_file(&engine, argv[1], MA_DATA_SOURCE_FLAG_DECODE /*| MA_DATA_SOURCE_FLAG_ASYNC | MA_DATA_SOURCE_FLAG_STREAM*/, &loadNotification, &group, &sound);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to load sound: %s\n", argv[1]);
|
||||
ma_engine_uninit(&engine);
|
||||
@@ -98,14 +96,14 @@ int main(int argc, char** argv)
|
||||
/*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(ma_engine_get_master_sound_group(&engine), 1.0f);
|
||||
ma_sound_group_set_pitch(&group, 1.1f);
|
||||
//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_sound_set_fade_in_milliseconds(&sound, 0, 1, 5000);
|
||||
/*ma_sound_set_volume(&sound, 0.25f);*/
|
||||
/*ma_sound_set_pitch(&sound, 1.2f);*/
|
||||
/*ma_sound_set_pitch(&sound, 1.1f);*/
|
||||
/*ma_sound_set_pan(&sound, 0.0f);*/
|
||||
/*ma_sound_set_looping(&sound, MA_TRUE);*/
|
||||
//ma_sound_seek_to_pcm_frame(&sound, 6000000);
|
||||
|
||||
@@ -824,7 +824,6 @@ struct ma_node_output_bus
|
||||
{
|
||||
/* Immutable. */
|
||||
ma_node* pNode; /* The node that owns this output bus. The input node. Will be null for dummy head and tail nodes. */
|
||||
ma_uint32 readCounter; /* For loop prevention. Compared with the current read count of the node graph. If larger, means a loop was encountered and reading is aborted and no samples read. */
|
||||
ma_uint8 outputBusIndex; /* The index of the output bus on pNode that this output bus represents. */
|
||||
ma_uint8 channels; /* The number of channels in the audio stream for this bus. */
|
||||
|
||||
@@ -849,8 +848,8 @@ struct ma_node_input_bus
|
||||
{
|
||||
/* Mutable via multiple threads. */
|
||||
ma_node_output_bus head; /* Dummy head node for simplifying some lock-free thread-safety stuff. */
|
||||
MA_ATOMIC ma_spinlock lock; /* Unfortunate lock, but significantly simplifies the implementation. Required for thread-safe attaching and detaching. */
|
||||
MA_ATOMIC ma_uint16 nextCounter; /* This is used to determine whether or not the input bus is finding the next node in the list. Used for thread safety when detaching output buses. */
|
||||
MA_ATOMIC ma_spinlock lock; /* Unfortunate lock, but significantly simplifies the implementation. Required for thread-safe attaching and detaching. */
|
||||
|
||||
/* Set once at startup. */
|
||||
ma_uint8 channels; /* The number of channels in the audio stream for this bus. */
|
||||
@@ -870,7 +869,6 @@ struct ma_node_base
|
||||
ma_uint16 cachedFrameCountOut;
|
||||
ma_uint16 cachedFrameCountIn;
|
||||
ma_uint16 consumedFrameCountIn;
|
||||
ma_uint32 readCounter; /* For loop prevention. Compared with the current read count of the node graph. If larger, means a loop was encountered and reading is aborted and no samples read. */
|
||||
|
||||
/* These variables are read and written between different threads. */
|
||||
MA_ATOMIC ma_node_state state; /* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
|
||||
@@ -915,7 +913,6 @@ struct ma_node_graph
|
||||
ma_node_base endpoint; /* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
|
||||
|
||||
/* Read and written by multiple threads. */
|
||||
MA_ATOMIC ma_uint32 readCounter; /* Nodes spin on this while they wait for reading for finish before returning from ma_node_uninit(). */
|
||||
MA_ATOMIC ma_bool8 isReading;
|
||||
};
|
||||
|
||||
@@ -2108,18 +2105,6 @@ static ma_bool8 ma_node_graph_is_reading(ma_node_graph* pNodeGraph)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ma_node_graph_increment_read_counter(ma_node_graph* pNodeGraph)
|
||||
{
|
||||
MA_ASSERT(pNodeGraph != NULL);
|
||||
c89atomic_fetch_add_32(&pNodeGraph->readCounter, 1);
|
||||
}
|
||||
|
||||
static ma_uint32 ma_node_graph_get_read_counter(ma_node_graph* pNodeGraph)
|
||||
{
|
||||
MA_ASSERT(pNodeGraph != NULL);
|
||||
return c89atomic_load_32(&pNodeGraph->readCounter);
|
||||
}
|
||||
|
||||
|
||||
static void ma_node_graph_endpoint_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
|
||||
{
|
||||
@@ -2226,7 +2211,6 @@ MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void*
|
||||
result = ma_node_read_pcm_frames(&pNodeGraph->endpoint, 0, (float*)ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, ma_format_f32, channels), framesToRead, &framesJustRead, ma_node_get_time(&pNodeGraph->endpoint));
|
||||
}
|
||||
ma_node_graph_set_is_reading(pNodeGraph, MA_FALSE);
|
||||
ma_node_graph_increment_read_counter(pNodeGraph);
|
||||
|
||||
totalFramesRead += framesJustRead;
|
||||
|
||||
@@ -2355,23 +2339,6 @@ static float ma_node_output_bus_get_volume(const ma_node_output_bus* pOutputBus)
|
||||
return c89atomic_load_f32((float*)&pOutputBus->volume);
|
||||
}
|
||||
|
||||
static ma_uint32 ma_node_output_bus_set_read_counter(ma_node_output_bus* pOutputBus, ma_uint32 newReadCounter)
|
||||
{
|
||||
ma_uint32 oldReadCounter;
|
||||
|
||||
MA_ASSERT(pOutputBus != NULL);
|
||||
|
||||
/*
|
||||
This function will only ever be called in a controlled environment (only on the audio thread,
|
||||
and never concurrently).
|
||||
*/
|
||||
oldReadCounter = pOutputBus->readCounter;
|
||||
pOutputBus->readCounter = newReadCounter;
|
||||
|
||||
return oldReadCounter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ma_result ma_node_input_bus_init(ma_uint32 channels, ma_node_input_bus* pInputBus)
|
||||
{
|
||||
@@ -2659,28 +2626,9 @@ static ma_result ma_node_input_bus_read_pcm_frames(ma_node* pInputNode, ma_node_
|
||||
|
||||
for (pOutputBus = pFirst; pOutputBus != NULL; pOutputBus = ma_node_input_bus_next(pInputBus, pOutputBus)) {
|
||||
ma_uint32 framesProcessed = 0;
|
||||
ma_uint32 readCounter;
|
||||
|
||||
MA_ASSERT(pOutputBus->pNode != NULL);
|
||||
|
||||
/*
|
||||
We need to grab the read counter at the start so we can set a new read counter first up. We
|
||||
need to do this first so that recursive reads can have access to the new counter. Note that
|
||||
we need to do this here and *not* in ma_node_read_pcm_frames() which would be the more
|
||||
intuitive option because we need to loop here in order to fill up as many frames as we can
|
||||
which would cause all iterations after the first to return 0 frames because of the loop
|
||||
detection logic getting triggered.
|
||||
*/
|
||||
readCounter = ma_node_output_bus_set_read_counter(pOutputBus, ma_node_graph_get_read_counter(ma_node_get_node_graph(pOutputBus->pNode)) + 1);
|
||||
|
||||
/*
|
||||
If the node's read counter is larger than that of the graph it means we've hit a loop and
|
||||
we need to skip this attachment.
|
||||
*/
|
||||
if (readCounter > ma_node_graph_get_read_counter(ma_node_get_node_graph(pOutputBus->pNode))) {
|
||||
continue; /* This output bus has already been processed by the current iteration. */
|
||||
}
|
||||
|
||||
if (pFramesOut != NULL) {
|
||||
/* Read. */
|
||||
float temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE / sizeof(float)];
|
||||
@@ -3407,9 +3355,10 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde
|
||||
requested, however we still need to clamp it to whatever can fit in the cache.
|
||||
|
||||
This will also be used as the basis for determining how many input frames to read. This is
|
||||
not ideal because it can result in too many input frames being read which introduces latency,
|
||||
however the alternative requires us to implement another callback in the node's vtable for
|
||||
calculating the required input frame count which I'm not willing to do.
|
||||
not ideal because it can result in too many input frames being read which introduces latency.
|
||||
To solve this, nodes can implement an optional callback called onGetRequiredInputFrameCount
|
||||
which is used as hint to miniaudio as to how many input frames it needs to read at a time. This
|
||||
callback is completely optional, and if it's not set, miniaudio will assume `frameCount`.
|
||||
|
||||
This function will be called multiple times for each period of time, once for each output node.
|
||||
We cannot read from each input node each time this function is called. Instead we need to check
|
||||
|
||||
@@ -83,17 +83,17 @@ int main(int argc, char** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = ma_node_attach_output_bus(&g_dataSourceNode, 0, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
|
||||
/*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 0
|
||||
#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.
|
||||
@@ -109,13 +109,9 @@ int main(int argc, char** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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_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);
|
||||
|
||||
/* 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, 0.5f);
|
||||
ma_node_set_output_bus_volume(&g_loopNode, 1, 0.5f);
|
||||
ma_node_set_output_bus_volume(&g_loopNode, 0, 1.0f);
|
||||
ma_node_set_output_bus_volume(&g_loopNode, 1, 1.0f);
|
||||
|
||||
|
||||
|
||||
@@ -135,17 +131,26 @@ int main(int argc, char** argv)
|
||||
/* 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);
|
||||
#else
|
||||
/* 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, &g_loopNode, 0);
|
||||
ma_node_attach_output_bus(&g_splitterNode, 1, &g_loopNode, 1);
|
||||
|
||||
/* Now loop back to the splitter node to form a loop. */
|
||||
/*ma_node_attach_output_bus(&g_loopNode, 1, &g_splitterNode, 0);*/
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user