
#include "mixer.hpp"

#include <iostream>

using std::cerr;
using std::cout;
using std::endl;

namespace Mixer {

AudioBuffer< Sint16 > live; //inited by 'init' below.

unsigned int underruns = 0;
unsigned int mixer_max = 0;

Sint16 *live_block = NULL;
unsigned int live_offset = 0;

void mixaudio(void *, Uint8 *_stream, int _len) {
	assert(_stream);
	assert(_len >= 0);
	Sint16 *stream = (Sint16 *)_stream;
	unsigned int len = (unsigned)_len / 2;
	//accumulate "live stream":
	{
		unsigned int done = 0;
		while (done < len) {
			if (!live_block) {
				live_block = live.try_receive_block();
				live_offset = 0;
			}
			if (!live_block) { //Live buffer underrun.
				++underruns;
				break;
			}
			assert(live_block);
			assert(live_offset < BufferBlockSize);
			unsigned int mix_length = len - done;
			if (mix_length > BufferBlockSize - live_offset) {
				mix_length = BufferBlockSize - live_offset;
			}
			for (unsigned int i = 0; i < mix_length; ++i) {
				stream[done+i] = live_block[live_offset+i];
			}
			live_offset += mix_length;
			done += mix_length;
			if (live_block && live_offset >= BufferBlockSize) {
				live.free_block(live_block);
				live_block = NULL;
			}
		}
	}
	unsigned int max = 0;
	//calculate max:
	for (unsigned int i = 0; i < len; ++i) {
		if ( stream[len] > (int)max) max = stream[len];
		if (-stream[len] > (int)max) max =-stream[len];
	}
	mixer_max = max;
	//done!
}

bool init() {
	live.init(5);
	live_block = NULL;
	live_offset = 0;
	SDL_AudioSpec spec;
	spec.freq = Rate;
	spec.format = AUDIO_S16SYS;
	spec.channels = 1;
	spec.samples = 1000;
	spec.callback = mixaudio;
	spec.userdata = NULL;
	int res = SDL_OpenAudio(&spec, NULL);
	if (res != 0) {
		std::cerr << "Error opening audio device" << std::endl;
		return false;
	}
	SDL_PauseAudio(0);
	return true;
}

void deinit() {
	cout << "Ditching audio...";cout.flush();
	SDL_CloseAudio();
	cout << " buffer..." << endl;
	cout << "SKIPPING!" << endl;
	//live.deinit();
	cout << "done." << endl;
}

}
