[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[WitchTech 00365] PCM再生で質問です



新参者のmanbow-Jと申します。以後よろしくお願いします。

早速質問なんですが、サウンドBIOSを使用してPCM再生をしようと
しているのですが、どうにもうまく行きません。
以下そのソースです。


#include	<sys/bios.h>
#include	<stdio.h>
#include	<fcntl.h>

void init_hblank( void );
void far hblank( void );
void restore_hook( void );

#ifdef LSI_C
int _asm_inline(char near *asm);
#define _CS _asm_inline("\tmov\tax,cs");
#define _DS _asm_inline("\tmov\tax,ds");
#endif

volatile	int	hcount;
int	vcount;
intvector_t	hbl;
intvector_t	hblold;
char	temp[256];

static	volatile	unsigned short	pcm_size;
static	unsigned char far	*pcm_ptr;
static	unsigned char far	*pcm_ptr0;

unsigned char wavetbl[] = {
	0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,
};

/*--------------------------------------------------------------
	メイン関数
 Input:		無し
 Output:	無し
--------------------------------------------------------------*/
void main( void )
{
	text_screen_init();

	pcm_ptr = NULL;
	pcm_size = 0;

	vcount = 0;
	hcount = 0;

	pcm_ptr0 = (unsigned char far *)mmap( "BNH.fr" );

	init_hblank();

	sound_init();
	if( (sound_get_output()&0x80) != 0 )	/* ヘッドフォン有り無し? */
		sound_set_output( 0x0e );
	else
		sound_set_output( 0x07 );

	sound_set_channel( 0x20 );				/* チャンネル2ボイスモードON */
	sound_set_wave(   1, wavetbl );			/* 以下、苦し紛れの設定 */
	sound_set_pitch(  1, 0x726 );
	sound_set_volume( 1, 0x88 );

	if( pcm_ptr0 != NULL ) {
		while( (key_press_check()&2) == 0 ) {
			sprintf( temp, "%x: %x", vcount, hcount );
			text_put_string( 0, 0, temp );
			sprintf( temp, "%lx: %lx", (long)pcm_ptr, (long)pcm_size );
			text_put_string( 0, 8, temp );

			if( (key_press_check()&4) != 0 ) {	/* Aが押されたら再生開始 */
				timer_disable( TIMER_HBLANK );
				pcm_ptr = pcm_ptr0;
				pcm_size = 16384;
				timer_enable( TIMER_HBLANK, TIMER_AUTOPRESET, 1 );
			}
			sys_wait(1);
			vcount++;
		}
	}
	restore_hook();
}



/*--------------------------------------------------------------
	H-Blankの初期化処理
 Input:
 Ouput:
--------------------------------------------------------------*/
void init_hblank( void )
{
/* H-Blankベクター(コールバックルーチン)設定 */
#ifdef LSI_C
	hbl.callback = (void (near *)())FP_OFF(hblank);
#else
	hbl.callback = (void (near *)())hblank;
#endif
	hbl.cs = _CS;
	hbl.ds = _DS;
	sys_interrupt_set_hook( SYS_INT_HBLANK_COUNTUP, &hbl, &hblold );
/* タイマー設定(H-Blank毎に割り込みは必ず発生) */
	timer_enable( TIMER_HBLANK, TIMER_AUTOPRESET, 1 );
}

/*--------------------------------------------------------------
	H-Blankのベクタ復帰処理
 Input:		無し
 Ouput:		無し
--------------------------------------------------------------*/
void restore_hook( void )
{
	timer_disable( TIMER_HBLANK );
	sys_interrupt_reset_hook( SYS_INT_HBLANK_COUNTUP, &hblold );
}

/*--------------------------------------------------------------
	H-Vbankカウントアップ時のコールバック
 Input:		無し
 Output:	無し
--------------------------------------------------------------*/
void far hblank( void )
{
	if( pcm_size ) {
		pcm_size--;
		sound_set_volume( 1, *pcm_ptr );
		pcm_ptr++;
	}
	hcount++;
}


H-Vlankの設定などはhcountの値が変化しているので割り込み関係は
うまく動いてくれているようです。

sound_set_channel( 0x20 );

上記の引数を、0x02に変更すると通常のPSGを再生するので
どうもチャンネル2のボイスモードの切り替えがうまく行っていない
ようなのですが、どうやってもうまく行きません。
わかる方、ぜひご教授ください。
hblank関数もコレだけ短いので多重割り込みも多分ないと思い
ますけど(ちょっと自信なし)

#ちなみにV-Sync〜V-Sync中のH-Sync発生回数をカウントしたら
#158回でした。よってPCMの再生周波数は
#158(H割り込み回数)*75(V割り込み回数)=11850Hz
#となります。多分コレが、正確な、再生周波数ではないかと思います。

それではまた。

--------------------------------------
Manbow-J manbow-j@hamal.freemail.ne.jp
--------------------------------------


ML Archives