[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