www.pudn.com > ncdzsrc.rar > streams.c


/*************************************************************************** 
 
	stream.c 
 
	サウンドストリーム処理 
 
***************************************************************************/ 
 
#include "neogeocd.h" 
 
#define MAX_CHANNLES 2 
#define BUFFER_LEN 16384 
 
 
/**************************************************************************** 
	ローカル変数 
 ***************************************************************************/ 
 
static INT16 stream_buffer[MAX_CHANNLES][BUFFER_LEN]; 
static int stream_buffer_pos; 
static int stream_sample_length; 
static void (*stream_callback)(INT16 **buffer, int length); 
 
static INT16 mixing_buffer[BUFFER_LEN]; 
static int samples_this_frame; 
static double volume; 
 
 
/*************************************************************************** 
	グローバル関数 
 ***************************************************************************/ 
 
/*------------------------------------------------------ 
 
	サウンドストリーム開始 
 
	引  数: なし 
	戻り値: 0:成功 1:失敗 
 
 -----------------------------------------------------*/ 
 
int streams_sh_start(void) 
{ 
	memset(mixing_buffer, 0, BUFFER_LEN * sizeof(INT16)); 
	memset(stream_buffer, 0, BUFFER_LEN * sizeof(INT16) * MAX_CHANNLES); 
	volume = 0; 
 
	if (sample_rate == 0) 
		return 0; 
 
	samples_this_frame = osd_start_audio_stream(); 
	if (samples_this_frame) 
	{ 
		stream_set_volume(); 
		return 0; 
	} 
 
	sample_rate = 0; 
	return 1; 
} 
 
 
/*------------------------------------------------------ 
 
	サウンドストリーム停止 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void streams_sh_stop(void) 
{ 
	if (sample_rate) 
		osd_stop_audio_stream(); 
} 
 
 
/*------------------------------------------------------ 
 
	ストリームの音量反映 
 
	引  数: INT16 val データの値 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
INLINE INT16 apply_volume(INT16 val) 
{ 
	INT32 value = (INT32)val * volume; 
 
	if (value >  32767) return  32767; 
	if (value < -32768) return -32768; 
	return (INT16)value; 
} 
 
 
/*------------------------------------------------------ 
 
	サウンドストリームの更新 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void streams_sh_update(void) 
{ 
	if (sample_rate) 
	{ 
		int i, buflen; 
		INT16 *buf[MAX_CHANNLES]; 
 
		buflen = samples_this_frame - stream_buffer_pos; 
 
		if (buflen > 0) 
		{ 
			for (i = 0; i < MAX_CHANNLES; i++) 
				buf[i] = stream_buffer[i] + stream_buffer_pos; 
 
			(*stream_callback)(buf, buflen); 
		} 
 
		stream_buffer_pos = 0; 
 
		for (i = 0; i < samples_this_frame; i++) 
		{ 
			mixing_buffer[i * 2 + 0] = stream_buffer[0][i]; 
			mixing_buffer[i * 2 + 1] = stream_buffer[1][i]; 
			stream_buffer[0][i] = stream_buffer[1][i] = 0; 
		} 
 
		if (volume != 1.0) 
		{ 
			for (i = 0; i < samples_this_frame * 2; i++) 
				mixing_buffer[i] = apply_volume(mixing_buffer[i]); 
		} 
 
		samples_this_frame = osd_update_audio_stream(mixing_buffer); 
	} 
} 
 
 
/*------------------------------------------------------ 
 
	ストリームの初期化 
 
	引  数: void (*callbaxk)(...) コールバック関数 
	        int length            ストリームのサイズ 
	戻り値: 1:成功 0:サウンド未使用 
 
 -----------------------------------------------------*/ 
 
int stream_init(void (*callback)(INT16 **buffer, int length)) 
{ 
	if (sample_rate) 
	{ 
		stream_buffer_pos = 0; 
		stream_sample_length = 1000000 / sample_rate; 
		stream_callback = callback; 
		return 1; 
	} 
	return 0; 
} 
 
 
/*------------------------------------------------------ 
 
	ストリームの更新 
 
	引  数: int min_interval 更新間隔の最小値(μ秒) 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void stream_update(int min_interval) 
{ 
	if (sample_rate) 
	{ 
		int i, buflen; 
		INT16 *buf[MAX_CHANNLES]; 
 
		buflen = sound_scalebufferpos(samples_this_frame) - stream_buffer_pos; 
 
		if (buflen * stream_sample_length > min_interval) 
		{ 
			for (i = 0; i < MAX_CHANNLES; i++) 
				buf[i] = stream_buffer[i] + stream_buffer_pos; 
 
			(*stream_callback)(buf, buflen); 
 
			stream_buffer_pos += buflen; 
		} 
	} 
} 
 
 
/*------------------------------------------------------ 
 
	サウンドストリームの音量設定 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void stream_set_volume(void) 
{ 
	volume = (double)options.sound_volume  / 100.0; 
}