mirror of
				https://github.com/NoelFB/blah.git
				synced 2025-11-04 01:41:34 +08:00 
			
		
		
		
	tested audio stuff on tinylink
This commit is contained in:
		@ -21,7 +21,7 @@ Platform* App::Internal::platform = nullptr;
 | 
			
		||||
Renderer* App::Internal::renderer = nullptr;
 | 
			
		||||
 | 
			
		||||
// Internal Audio bool
 | 
			
		||||
bool Audio::Internal::is_init = false;
 | 
			
		||||
bool Internal::audio_is_init = false;
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
@ -117,12 +117,12 @@ bool App::run(const Config* c)
 | 
			
		||||
 | 
			
		||||
	// initialize audio
 | 
			
		||||
	{
 | 
			
		||||
		if (!Audio::Internal::is_init) {
 | 
			
		||||
		if (!Blah::Internal::audio_is_init) {
 | 
			
		||||
			int more_on_emscripten = 1;
 | 
			
		||||
			#ifdef __EMSCRIPTEN__
 | 
			
		||||
			more_on_emscripten = 4;
 | 
			
		||||
			#endif
 | 
			
		||||
			Audio::Internal::is_init = Audio::Internal::init(NULL, c->audio_frequency_in_Hz, 1024 * more_on_emscripten);
 | 
			
		||||
			Blah::Internal::audio_is_init = Blah::Internal::audio_init(NULL, c->audio_frequency_in_Hz, 1024 * more_on_emscripten);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -280,6 +280,9 @@ void App::Internal::iterate()
 | 
			
		||||
		renderer->after_render();
 | 
			
		||||
		platform->present();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update audio
 | 
			
		||||
	Blah::Internal::audio_update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void App::Internal::shutdown()
 | 
			
		||||
@ -300,8 +303,8 @@ void App::Internal::shutdown()
 | 
			
		||||
		delete platform;
 | 
			
		||||
	platform = nullptr;
 | 
			
		||||
 | 
			
		||||
	Audio::Internal::shutdown();
 | 
			
		||||
	Audio::Internal::is_init = false;
 | 
			
		||||
	Blah::Internal::audio_shutdown();
 | 
			
		||||
	Blah::Internal::audio_is_init = false;
 | 
			
		||||
 | 
			
		||||
	// clear static App state
 | 
			
		||||
	app_config = Config();
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#include "blah_audio.h"
 | 
			
		||||
#include "blah_time.h"
 | 
			
		||||
 | 
			
		||||
#define STB_VORBIS_HEADER_ONLY
 | 
			
		||||
#include "third_party/stb_vorbis.c"
 | 
			
		||||
@ -11,7 +12,7 @@ namespace Blah
 | 
			
		||||
{
 | 
			
		||||
	namespace Internal
 | 
			
		||||
	{
 | 
			
		||||
		bool init(void* os_handle, unsigned play_frequency_in_Hz, int buffered_samples)
 | 
			
		||||
		bool audio_init(void* os_handle, unsigned play_frequency_in_Hz, int buffered_samples)
 | 
			
		||||
		{
 | 
			
		||||
			cs_error_t err = cs_init(os_handle, play_frequency_in_Hz, buffered_samples, NULL);
 | 
			
		||||
			if (err != CUTE_SOUND_ERROR_NONE) {
 | 
			
		||||
@ -20,12 +21,18 @@ namespace Blah
 | 
			
		||||
			} else {
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			cs_spawn_mix_thread();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void shutdown()
 | 
			
		||||
		void audio_shutdown()
 | 
			
		||||
		{
 | 
			
		||||
			cs_shutdown();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void audio_update()
 | 
			
		||||
		{
 | 
			
		||||
			cs_update(Time::delta);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Audio::Audio(void* audio)
 | 
			
		||||
@ -74,7 +81,7 @@ namespace Blah
 | 
			
		||||
 | 
			
		||||
		// load wav file from memory using cute_sound.h
 | 
			
		||||
		cs_error_t err;
 | 
			
		||||
		void* audio = cs_read_mem_wav((void*)buffer.data(), (size_t)buffer.size(), &err);
 | 
			
		||||
		void* audio = cs_read_mem_wav((void*)buffer.data(), stream.length(), &err);
 | 
			
		||||
		if (!audio) {
 | 
			
		||||
			Log::error(cs_error_as_string(err));
 | 
			
		||||
			return AudioRef();
 | 
			
		||||
@ -98,7 +105,7 @@ namespace Blah
 | 
			
		||||
 | 
			
		||||
		// load ogg file from memory using cute_sound.h
 | 
			
		||||
		cs_error_t err;
 | 
			
		||||
		void* audio = cs_read_mem_ogg((void*)buffer.data(), (size_t)buffer.size(), &err);
 | 
			
		||||
		void* audio = cs_read_mem_ogg((void*)buffer.data(), stream.length(), &err);
 | 
			
		||||
		if (!audio) {
 | 
			
		||||
			Log::error(cs_error_as_string(err));
 | 
			
		||||
			return AudioRef();
 | 
			
		||||
 | 
			
		||||
@ -37,17 +37,15 @@ namespace Blah
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	namespace Audio
 | 
			
		||||
	namespace Internal
 | 
			
		||||
	{
 | 
			
		||||
		namespace Internal
 | 
			
		||||
		{
 | 
			
		||||
			extern bool is_init;
 | 
			
		||||
		extern bool audio_is_init;
 | 
			
		||||
 | 
			
		||||
			// Pass in NULL for `os_handle`, except for the DirectSound backend this should be hwnd.
 | 
			
		||||
			// play_frequency_in_Hz depends on your audio file, 44100 seems to be fine.
 | 
			
		||||
			// buffered_samples is clamped to be at least 1024.
 | 
			
		||||
			bool init(void* os_handle, unsigned play_frequency_in_Hz, int buffered_samples);
 | 
			
		||||
			void shutdown();
 | 
			
		||||
		}
 | 
			
		||||
		// Pass in NULL for `os_handle`, except for the DirectSound backend this should be hwnd.
 | 
			
		||||
		// play_frequency_in_Hz depends on your audio file, 44100 seems to be fine.
 | 
			
		||||
		// buffered_samples is clamped to be at least 1024.
 | 
			
		||||
		bool audio_init(void* os_handle, unsigned play_frequency_in_Hz, int buffered_samples);
 | 
			
		||||
		void audio_shutdown();
 | 
			
		||||
		void audio_update();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								src/third_party/cute_sound.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										100
									
								
								src/third_party/cute_sound.h
									
									
									
									
										vendored
									
									
								
							@ -1339,7 +1339,6 @@ typedef struct cs_context_t
 | 
			
		||||
	cs_inst_page_t* pages /* = NULL */;
 | 
			
		||||
	cs_list_t playing_sounds;
 | 
			
		||||
	cs_list_t free_sounds;
 | 
			
		||||
	void* mem_ctx /* = NULL */;
 | 
			
		||||
 | 
			
		||||
	unsigned latency_samples;
 | 
			
		||||
	int Hz;
 | 
			
		||||
@ -1393,6 +1392,7 @@ typedef struct cs_context_t
 | 
			
		||||
#endif
 | 
			
		||||
} cs_context_t;
 | 
			
		||||
 | 
			
		||||
void* s_mem_ctx;
 | 
			
		||||
cs_context_t* s_ctx = NULL;
 | 
			
		||||
 | 
			
		||||
void cs_sleep(int milliseconds)
 | 
			
		||||
@ -1708,21 +1708,21 @@ cs_error_t cs_init(void* os_handle, unsigned play_frequency_in_Hz, int buffered_
 | 
			
		||||
	s_ctx->music_next = NULL;
 | 
			
		||||
	s_ctx->audio_sources_to_free_capacity = 32;
 | 
			
		||||
	s_ctx->audio_sources_to_free_size = 0;
 | 
			
		||||
	s_ctx->audio_sources_to_free = (cs_audio_source_t**)CUTE_SOUND_ALLOC(sizeof(cs_audio_source_t*) * s_ctx->audio_sources_to_free_capacity, s_ctx->mem_ctx);
 | 
			
		||||
	s_ctx->audio_sources_to_free = (cs_audio_source_t**)CUTE_SOUND_ALLOC(sizeof(cs_audio_source_t*) * s_ctx->audio_sources_to_free_capacity, s_mem_ctx);
 | 
			
		||||
	s_ctx->instance_id_gen = 1;
 | 
			
		||||
	hashtable_init(&s_ctx->instance_map, sizeof(cs_audio_source_t*), 1024, user_allocator_context);
 | 
			
		||||
	s_ctx->pages = NULL;
 | 
			
		||||
	cs_list_init(&s_ctx->playing_sounds);
 | 
			
		||||
	cs_list_init(&s_ctx->free_sounds);
 | 
			
		||||
	s_add_page();
 | 
			
		||||
	s_ctx->mem_ctx = user_allocator_context;
 | 
			
		||||
	s_mem_ctx = user_allocator_context;
 | 
			
		||||
	s_ctx->latency_samples = buffered_samples;
 | 
			
		||||
	s_ctx->Hz = play_frequency_in_Hz;
 | 
			
		||||
	s_ctx->bps = bps;
 | 
			
		||||
	s_ctx->wide_count = wide_count;
 | 
			
		||||
	s_ctx->floatA = (cs__m128*)cs_malloc16(sizeof(cs__m128) * wide_count, s_ctx->mem_ctx);
 | 
			
		||||
	s_ctx->floatB = (cs__m128*)cs_malloc16(sizeof(cs__m128) * wide_count, s_ctx->mem_ctx);
 | 
			
		||||
	s_ctx->samples = (cs__m128i*)cs_malloc16(sizeof(cs__m128i) * wide_count, s_ctx->mem_ctx);
 | 
			
		||||
	s_ctx->floatA = (cs__m128*)cs_malloc16(sizeof(cs__m128) * wide_count, s_mem_ctx);
 | 
			
		||||
	s_ctx->floatB = (cs__m128*)cs_malloc16(sizeof(cs__m128) * wide_count, s_mem_ctx);
 | 
			
		||||
	s_ctx->samples = (cs__m128i*)cs_malloc16(sizeof(cs__m128i) * wide_count, s_mem_ctx);
 | 
			
		||||
	s_ctx->running = true;
 | 
			
		||||
	s_ctx->separate_thread = false;
 | 
			
		||||
	s_ctx->sleep_milliseconds = 0;
 | 
			
		||||
@ -1802,25 +1802,37 @@ void cs_shutdown()
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!cs_list_empty(&s_ctx->playing_sounds)) {
 | 
			
		||||
		cs_list_node_t* playing_node = cs_list_begin(&s_ctx->playing_sounds);
 | 
			
		||||
		cs_list_node_t* end_node = cs_list_end(&s_ctx->playing_sounds);
 | 
			
		||||
		do {
 | 
			
		||||
			cs_list_node_t* next_node = playing_node->next;
 | 
			
		||||
			cs_sound_inst_t* playing = CUTE_SOUND_LIST_HOST(cs_sound_inst_t, node, playing_node);
 | 
			
		||||
			cs_audio_source_t* audio = playing->audio;
 | 
			
		||||
			if (audio) audio->playing_count = 0;
 | 
			
		||||
			playing_node = next_node;
 | 
			
		||||
		} while (playing_node != end_node);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cs_inst_page_t* page = s_ctx->pages;
 | 
			
		||||
	while (page) {
 | 
			
		||||
		cs_inst_page_t* next = page->next;
 | 
			
		||||
		CUTE_SOUND_FREE(page, s_ctx->mem_ctx);
 | 
			
		||||
		CUTE_SOUND_FREE(page, s_mem_ctx);
 | 
			
		||||
		page = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < s_ctx->audio_sources_to_free_size; ++i) {
 | 
			
		||||
		cs_audio_source_t* audio = s_ctx->audio_sources_to_free[i];
 | 
			
		||||
		cs_free16(audio->channels[0], s_ctx->mem_ctx);
 | 
			
		||||
		CUTE_SOUND_FREE(audio, s_ctx->mem_ctx);
 | 
			
		||||
		cs_free16(audio->channels[0], s_mem_ctx);
 | 
			
		||||
		CUTE_SOUND_FREE(audio, s_mem_ctx);
 | 
			
		||||
	}
 | 
			
		||||
	CUTE_SOUND_FREE(s_ctx->audio_sources_to_free, s_ctx->mem_ctx);
 | 
			
		||||
	CUTE_SOUND_FREE(s_ctx->audio_sources_to_free, s_mem_ctx);
 | 
			
		||||
 | 
			
		||||
	cs_free16(s_ctx->floatA, s_ctx->mem_ctx);
 | 
			
		||||
	cs_free16(s_ctx->floatB, s_ctx->mem_ctx);
 | 
			
		||||
	cs_free16(s_ctx->samples, s_ctx->mem_ctx);
 | 
			
		||||
	cs_free16(s_ctx->floatA, s_mem_ctx);
 | 
			
		||||
	cs_free16(s_ctx->floatB, s_mem_ctx);
 | 
			
		||||
	cs_free16(s_ctx->samples, s_mem_ctx);
 | 
			
		||||
	hashtable_term(&s_ctx->instance_map);
 | 
			
		||||
	void* mem_ctx = s_ctx->mem_ctx;
 | 
			
		||||
	void* mem_ctx = s_mem_ctx;
 | 
			
		||||
	(void)mem_ctx;
 | 
			
		||||
	CUTE_SOUND_FREE(s_ctx, mem_ctx);
 | 
			
		||||
	s_ctx = NULL;
 | 
			
		||||
@ -2227,7 +2239,11 @@ void cs_mix()
 | 
			
		||||
			playing->active = false;
 | 
			
		||||
 | 
			
		||||
			if (playing->audio) {
 | 
			
		||||
				playing->audio->playing_count -= 1;
 | 
			
		||||
				if (s_ctx->running) {
 | 
			
		||||
					playing->audio->playing_count -= 1;
 | 
			
		||||
				} else {
 | 
			
		||||
					playing->audio->playing_count = 0;
 | 
			
		||||
				}
 | 
			
		||||
				CUTE_SOUND_ASSERT(playing->audio->playing_count >= 0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -2276,8 +2292,8 @@ void cs_mix()
 | 
			
		||||
	for (int i = 0; i < s_ctx->audio_sources_to_free_size;) {
 | 
			
		||||
		cs_audio_source_t* audio = s_ctx->audio_sources_to_free[i];
 | 
			
		||||
		if (audio->playing_count == 0) {
 | 
			
		||||
			cs_free16(audio->channels[0], s_ctx->mem_ctx);
 | 
			
		||||
			CUTE_SOUND_FREE(audio, s_ctx->mem_ctx);
 | 
			
		||||
			cs_free16(audio->channels[0], s_mem_ctx);
 | 
			
		||||
			CUTE_SOUND_FREE(audio, s_mem_ctx);
 | 
			
		||||
			s_ctx->audio_sources_to_free[i] = s_ctx->audio_sources_to_free[--s_ctx->audio_sources_to_free_size];
 | 
			
		||||
		} else {
 | 
			
		||||
			++i;
 | 
			
		||||
@ -2376,10 +2392,10 @@ static void cs_last_element(cs__m128* a, int i, int j, int16_t* samples, int off
 | 
			
		||||
cs_audio_source_t* cs_load_wav(const char* path, cs_error_t* err /* = NULL */)
 | 
			
		||||
{
 | 
			
		||||
	int size;
 | 
			
		||||
	void* wav = cs_read_file_to_memory(path, &size, s_ctx->mem_ctx);
 | 
			
		||||
	void* wav = cs_read_file_to_memory(path, &size, s_mem_ctx);
 | 
			
		||||
	if (!wav) return NULL;
 | 
			
		||||
	cs_audio_source_t* audio = cs_read_mem_wav(wav, size, err);
 | 
			
		||||
	CUTE_SOUND_FREE(wav, s_ctx->mem_ctx);
 | 
			
		||||
	CUTE_SOUND_FREE(wav, s_mem_ctx);
 | 
			
		||||
	return audio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2431,7 +2447,7 @@ cs_audio_source_t* cs_read_mem_wav(const void* memory, size_t size, cs_error_t*
 | 
			
		||||
		data = cs_next(data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	audio = (cs_audio_source_t*)CUTE_SOUND_ALLOC(sizeof(cs_audio_source_t), s_ctx->mem_ctx);
 | 
			
		||||
	audio = (cs_audio_source_t*)CUTE_SOUND_ALLOC(sizeof(cs_audio_source_t), s_mem_ctx);
 | 
			
		||||
	CUTE_SOUND_MEMSET(audio, 0, sizeof(*audio));
 | 
			
		||||
	audio->sample_rate = (int)fmt.nSamplesPerSec;
 | 
			
		||||
 | 
			
		||||
@ -2505,22 +2521,28 @@ cs_audio_source_t* cs_read_mem_wav(const void* memory, size_t size, cs_error_t*
 | 
			
		||||
 | 
			
		||||
void cs_free_audio_source(cs_audio_source_t* audio)
 | 
			
		||||
{
 | 
			
		||||
	cs_lock();
 | 
			
		||||
	if (audio->playing_count == 0) {
 | 
			
		||||
		cs_free16(audio->channels[0], s_ctx->mem_ctx);
 | 
			
		||||
		CUTE_SOUND_FREE(audio, s_ctx->mem_ctx);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (s_ctx->audio_sources_to_free_size == s_ctx->audio_sources_to_free_capacity) {
 | 
			
		||||
			int new_capacity = s_ctx->audio_sources_to_free_capacity * 2;
 | 
			
		||||
			cs_audio_source_t** new_sources = (cs_audio_source_t**)CUTE_SOUND_ALLOC(new_capacity, s_ctx->mem_ctx);
 | 
			
		||||
			CUTE_SOUND_MEMCPY(new_sources, s_ctx->audio_sources_to_free, sizeof(cs_audio_source_t*) * s_ctx->audio_sources_to_free_size);
 | 
			
		||||
			CUTE_SOUND_FREE(s_ctx->audio_sources_to_free, s_ctx->mem_ctx);
 | 
			
		||||
			s_ctx->audio_sources_to_free = new_sources;
 | 
			
		||||
			s_ctx->audio_sources_to_free_capacity = new_capacity;
 | 
			
		||||
	if (s_ctx) {
 | 
			
		||||
		cs_lock();
 | 
			
		||||
		if (audio->playing_count == 0) {
 | 
			
		||||
			cs_free16(audio->channels[0], s_mem_ctx);
 | 
			
		||||
			CUTE_SOUND_FREE(audio, s_mem_ctx);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (s_ctx->audio_sources_to_free_size == s_ctx->audio_sources_to_free_capacity) {
 | 
			
		||||
				int new_capacity = s_ctx->audio_sources_to_free_capacity * 2;
 | 
			
		||||
				cs_audio_source_t** new_sources = (cs_audio_source_t**)CUTE_SOUND_ALLOC(new_capacity, s_mem_ctx);
 | 
			
		||||
				CUTE_SOUND_MEMCPY(new_sources, s_ctx->audio_sources_to_free, sizeof(cs_audio_source_t*) * s_ctx->audio_sources_to_free_size);
 | 
			
		||||
				CUTE_SOUND_FREE(s_ctx->audio_sources_to_free, s_mem_ctx);
 | 
			
		||||
				s_ctx->audio_sources_to_free = new_sources;
 | 
			
		||||
				s_ctx->audio_sources_to_free_capacity = new_capacity;
 | 
			
		||||
			}
 | 
			
		||||
			s_ctx->audio_sources_to_free[s_ctx->audio_sources_to_free_size++] = audio;
 | 
			
		||||
		}
 | 
			
		||||
		s_ctx->audio_sources_to_free[s_ctx->audio_sources_to_free_size++] = audio;
 | 
			
		||||
		cs_unlock();
 | 
			
		||||
	} else {
 | 
			
		||||
		CUTE_SOUND_ASSERT(audio->playing_count == 0);
 | 
			
		||||
		cs_free16(audio->channels[0], NULL);
 | 
			
		||||
		CUTE_SOUND_FREE(audio, s_mem_ctx);
 | 
			
		||||
	}
 | 
			
		||||
	cs_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if CUTE_SOUND_PLATFORM == CUTE_SOUND_SDL && defined(SDL_rwops_h_) && defined(CUTE_SOUND_SDL_RWOPS)
 | 
			
		||||
@ -2556,10 +2578,10 @@ void cs_free_audio_source(cs_audio_source_t* audio)
 | 
			
		||||
	cs_audio_source_t* cs_load_wav_rw(SDL_RWops* context, cs_error_t* err)
 | 
			
		||||
	{
 | 
			
		||||
		int size;
 | 
			
		||||
		char* wav = (char*)cs_read_rw_to_memory(context, &size, s_ctx->mem_ctx);
 | 
			
		||||
		char* wav = (char*)cs_read_rw_to_memory(context, &size, s_mem_ctx);
 | 
			
		||||
		if (!memory) return NULL;
 | 
			
		||||
		cs_audio_source_t* audio = cs_read_mem_wav(wav, length, err);
 | 
			
		||||
		CUTE_SOUND_FREE(wav, s_ctx->mem_ctx);
 | 
			
		||||
		CUTE_SOUND_FREE(wav, s_mem_ctx);
 | 
			
		||||
		return audio;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -2577,7 +2599,7 @@ cs_audio_source_t* cs_read_mem_ogg(const void* memory, size_t length, cs_error_t
 | 
			
		||||
	int sample_rate;
 | 
			
		||||
	int sample_count = stb_vorbis_decode_memory((const unsigned char*)memory, (int)length, &channel_count, &sample_rate, &samples);
 | 
			
		||||
	if (sample_count <= 0) { if (err) *err = CUTE_SOUND_ERROR_STB_VORBIS_DECODE_FAILED; return NULL; }
 | 
			
		||||
	audio = (cs_audio_source_t*)CUTE_SOUND_ALLOC(sizeof(cs_audio_source_t), s_ctx->mem_ctx);
 | 
			
		||||
	audio = (cs_audio_source_t*)CUTE_SOUND_ALLOC(sizeof(cs_audio_source_t), s_mem_ctx);
 | 
			
		||||
	CUTE_SOUND_MEMSET(audio, 0, sizeof(*audio));
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
@ -2663,10 +2685,10 @@ cs_audio_source_t* cs_load_ogg(const char* path, cs_error_t* err)
 | 
			
		||||
	cs_audio_source_t* cs_load_ogg_rw(SDL_RWops* rw, cs_error_t* err)
 | 
			
		||||
	{
 | 
			
		||||
		int length;
 | 
			
		||||
		void* memory = cs_read_rw_to_memory(rw, &length, s_ctx->mem_ctx);
 | 
			
		||||
		void* memory = cs_read_rw_to_memory(rw, &length, s_mem_ctx);
 | 
			
		||||
		if (!memory) return NULL;
 | 
			
		||||
		cs_audio_source_t* audio = cs_read_ogg_wav(memory, length, err);
 | 
			
		||||
		CUTE_SOUND_FREE(memory, s_ctx->mem_ctx);
 | 
			
		||||
		CUTE_SOUND_FREE(memory, s_mem_ctx);
 | 
			
		||||
		return audio;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user