forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			119 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <AL/al.h>
 | |
| #include <AL/alc.h>
 | |
| #include <assert.h>
 | |
| #include <emscripten.h>
 | |
| #include <kinc/audio2/audio.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| static kinc_a2_buffer_t a2_buffer;
 | |
| 
 | |
| static ALCdevice *device = NULL;
 | |
| static ALCcontext *context = NULL;
 | |
| static unsigned int channels = 0;
 | |
| static unsigned int bits = 0;
 | |
| static ALenum format = 0;
 | |
| static ALuint source = 0;
 | |
| 
 | |
| static bool audioRunning = false;
 | |
| #define BUFSIZE 4096
 | |
| static short buf[BUFSIZE];
 | |
| #define NUM_BUFFERS 3
 | |
| 
 | |
| static uint32_t samples_per_second = 44100;
 | |
| 
 | |
| static void copySample(void *buffer) {
 | |
| 	float left_value = *(float *)&a2_buffer.channels[0][a2_buffer.read_location];
 | |
| 	float right_value = *(float *)&a2_buffer.channels[1][a2_buffer.read_location];
 | |
| 	a2_buffer.read_location += 1;
 | |
| 	if (a2_buffer.read_location >= a2_buffer.data_size) {
 | |
| 		a2_buffer.read_location = 0;
 | |
| 	}
 | |
| 	((int16_t *)buffer)[0] = (int16_t)(left_value * 32767);
 | |
| 	((int16_t *)buffer)[1] = (int16_t)(right_value * 32767);
 | |
| }
 | |
| 
 | |
| static void streamBuffer(ALuint buffer) {
 | |
| 	if (kinc_a2_internal_callback(&a2_buffer, BUFSIZE / 2)) {
 | |
| 		for (int i = 0; i < BUFSIZE; i += 2) {
 | |
| 			copySample(&buf[i]);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	alBufferData(buffer, format, buf, BUFSIZE * 2, samples_per_second);
 | |
| }
 | |
| 
 | |
| static void iter() {
 | |
| 	if (!audioRunning) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	ALint processed;
 | |
| 	alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
 | |
| 
 | |
| 	if (processed <= 0) {
 | |
| 		return;
 | |
| 	}
 | |
| 	while (processed--) {
 | |
| 		ALuint buffer;
 | |
| 		alSourceUnqueueBuffers(source, 1, &buffer);
 | |
| 		streamBuffer(buffer);
 | |
| 		alSourceQueueBuffers(source, 1, &buffer);
 | |
| 	}
 | |
| 
 | |
| 	ALint playing;
 | |
| 	alGetSourcei(source, AL_SOURCE_STATE, &playing);
 | |
| 	if (playing != AL_PLAYING) {
 | |
| 		alSourcePlay(source);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static bool a2_initialized = false;
 | |
| 
 | |
| void kinc_a2_init() {
 | |
| 	if (a2_initialized) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	kinc_a2_internal_init();
 | |
| 	a2_initialized = true;
 | |
| 
 | |
| 	a2_buffer.read_location = 0;
 | |
| 	a2_buffer.write_location = 0;
 | |
| 	a2_buffer.data_size = 128 * 1024;
 | |
| 	a2_buffer.channel_count = 2;
 | |
| 	a2_buffer.channels[0] = (float*)malloc(a2_buffer.data_size * sizeof(float));
 | |
| 	a2_buffer.channels[1] = (float*)malloc(a2_buffer.data_size * sizeof(float));
 | |
| 
 | |
| 	audioRunning = true;
 | |
| 
 | |
| 	device = alcOpenDevice(NULL);
 | |
| 	context = alcCreateContext(device, NULL);
 | |
| 	alcMakeContextCurrent(context);
 | |
| 	format = AL_FORMAT_STEREO16;
 | |
| 
 | |
| 	ALuint buffers[NUM_BUFFERS];
 | |
| 	alGenBuffers(NUM_BUFFERS, buffers);
 | |
| 	alGenSources(1, &source);
 | |
| 
 | |
| 	streamBuffer(buffers[0]);
 | |
| 	streamBuffer(buffers[1]);
 | |
| 	streamBuffer(buffers[2]);
 | |
| 
 | |
| 	alSourceQueueBuffers(source, NUM_BUFFERS, buffers);
 | |
| 
 | |
| 	alSourcePlay(source);
 | |
| }
 | |
| 
 | |
| void kinc_a2_update() {
 | |
| 	iter();
 | |
| }
 | |
| 
 | |
| void kinc_a2_shutdown() {
 | |
| 	audioRunning = false;
 | |
| }
 | |
| 
 | |
| uint32_t kinc_a2_samples_per_second(void) {
 | |
| 	return samples_per_second;
 | |
| }
 |