diff --git a/mini_al.h b/mini_al.h index b3c349dd..18c4d0f6 100644 --- a/mini_al.h +++ b/mini_al.h @@ -2013,7 +2013,25 @@ mal_result mal_decoder_uninit(mal_decoder* pDecoder); mal_uint64 mal_decoder_read(mal_decoder* pDecoder, mal_uint64 frameCount, void* pFramesOut); mal_result mal_decoder_seek_to_frame(mal_decoder* pDecoder, mal_uint64 frameIndex); -#endif +#endif // MAL_NO_DECODING + + +/////////////////////////////////////////////////////////////////////////////// +// +// Generation +// +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + double amplitude; + double periodsPerSecond; + double delta; + double time; +} mal_sine_wave; + +mal_result mal_sine_wave_init(double amplitude, double period, mal_uint32 sampleRate, mal_sine_wave* pSignWave); +mal_uint64 mal_sine_wave_read(mal_sine_wave* pSignWave, mal_uint64 count, float* pSamples); #ifdef __cplusplus @@ -2032,6 +2050,7 @@ mal_result mal_decoder_seek_to_frame(mal_decoder* pDecoder, mal_uint64 frameInde #ifdef MAL_IMPLEMENTATION #include #include // For INT_MAX +#include // sin(), etc. #ifdef MAL_WIN32 #include @@ -2078,6 +2097,13 @@ mal_result mal_decoder_seek_to_frame(mal_decoder* pDecoder, mal_uint64 frameInde #endif #endif +#ifndef MAL_PI +#define MAL_PI 3.14159265358979323846264f +#endif +#ifndef MAL_PI_D +#define MAL_PI_D 3.14159265358979323846264 +#endif + // Unfortunately using runtime linking for pthreads causes problems. This has occurred for me when testing on FreeBSD. When // using runtime linking, deadlocks can occur (for me it happens when loading data from fread()). It turns out that doing // compile-time linking fixes this. I'm not sure why this happens, but this is the safest way I can think of to continue. To @@ -19325,6 +19351,62 @@ mal_result mal_decoder_seek_to_frame(mal_decoder* pDecoder, mal_uint64 frameInde } #endif // MAL_NO_DECODING + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// GENERATION +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +mal_result mal_sine_wave_init(double amplitude, double periodsPerSecond, mal_uint32 sampleRate, mal_sine_wave* pSignWave) +{ + if (pSignWave == NULL) { + return MAL_INVALID_ARGS; + } + mal_zero_object(pSignWave); + + if (amplitude == 0 || periodsPerSecond == 0) { + return MAL_INVALID_ARGS; + } + + if (amplitude > 1) { + amplitude = 1; + } + if (amplitude < -1) { + amplitude = -1; + } + + pSignWave->amplitude = amplitude; + pSignWave->periodsPerSecond = periodsPerSecond; + pSignWave->delta = MAL_PI_D*2 / sampleRate; + pSignWave->time = 0; + + return MAL_SUCCESS; +} + +mal_uint64 mal_sine_wave_read(mal_sine_wave* pSignWave, mal_uint64 count, float* pSamples) +{ + if (pSignWave == NULL) { + return 0; + } + + if (pSamples != NULL) { + for (mal_uint64 i = 0; i < count; i += 1) { + pSamples[i] = (float)(sin(pSignWave->time * pSignWave->periodsPerSecond) * pSignWave->amplitude); + pSignWave->time += pSignWave->delta; + } + } else { + pSignWave->time += pSignWave->delta * count; + } + + return count; +} + + #endif // MAL_IMPLEMENTATION @@ -19355,6 +19437,7 @@ mal_result mal_decoder_seek_to_frame(mal_decoder* pDecoder, mal_uint64 frameInde // - Remove dependency on audioclient.h for the WASAPI backend. This fixes build issues with some // distributions of MinGW. // - Add support for configuring the priority of the worker thread. +// - Add a sine wave generator. // - Introduce the notion of standard channel maps. Use mal_get_standard_channel_map(). // - Introduce the notion of default device configurations. A default config uses the same configuration // as the backend's internal device, and as such results in a pass-through data transmission pipeline.