📄 sing.c
字号:
g_sample_buffer0_ptr = buffer + 4;
g_sample_buffer1_ptr = buffer + 4 + SINGLE_BUFFER_SIZE__SHORT;
/* */
/* Buffer filling timing parameter */
/* */
g_file_access_reserve_timing = (((FRAME_PER_BUFFER * NUM_OF_BUFFER_UNITS) * 8) / 10) + APPL_BUFFER_FILLING_OFFSET;
g_file_access_reserve_timing %= (FRAME_PER_BUFFER * NUM_OF_BUFFER_UNITS);
/* */
/* Command to Audio device */
/* */
send_init_commands( dvi_ptr );
/* */
/* Initial buffer filling */
/* */
(*g_buffer_fill_method)( (unsigned char *)g_sample_buffer0_ptr );
(*g_buffer_fill_method)( (unsigned char *)g_sample_buffer1_ptr );
return ( 0 );
}
unsigned short open_music_file( char *filename )
{
wave_header wave_head;
unsigned int readsz;
/* */
/* Open the music file */
/* */
if ( 0 != (_dos_open( filename, O_RDONLY, &g_file_handle )) )
{
mprintf( RED, CONTINUE, "error @ wave file open\r\n" );
return ( 1 );
}
/* */
/* Checking "wave" header */
/* */
_dos_read( g_file_handle, &wave_head, sizeof( wave_header ), &readsz );
if ( !strncmp( wave_head.wave_h, "WAVE", 3 ) ) // It may be wave format!
{
if ( wave_head.data_speed != 176400L )
{
#ifndef _MiniKit
mprintf( LIGHTGREEN, CONTINUE, " \".wav file may not Kenobi2 compatible format.\"\r\n" );
#else
printf( "\".wav file may not Kenobi2 compatible format.\"\n" );
#endif
return ( 2 );
}
else
{
int min,
sec,
total_sec;
total_sec = wave_head.data_sample_size_in_bytes / 176400L;
min = total_sec / 60;
sec = total_sec % 60;
#ifndef _MiniKit
mprintf( LIGHTGREEN, CONTINUE, " play time %dmin %02dsec (%dseconds)\"\r\n", min, sec, total_sec );
#else
printf( " play time %dmin %02dsec (%dseconds)\"\r\n", min, sec, total_sec );
#endif
}
}
else
{
#ifndef _MiniKit
mprintf( LIGHTGREEN, CONTINUE, " The file is not in \".wav\" format. It will play as raw data.\"\r\n" );
#else
printf( " The file is not in \".wav\" format. It will play as raw data.\"\n" );
#endif
// re-open to seek reset
_dos_close( g_file_handle );
if ( 0 != (_dos_open( filename, O_RDONLY, &g_file_handle )) )
{
mprintf( RED, CONTINUE, "error @ wave file open\r\n" );
return ( 1 );
}
}
return ( 0 );
}
unsigned int sing_buffer_fill_from_file( unsigned char *buffer_ptr )
{
unsigned int readsz;
if ( FILE_ACCESS_READ != dos_read_exclusive( g_file_handle, buffer_ptr, SINGLE_BUFFER_SIZE__BYTES, &readsz, FILE_ACCESS_FREE, FILE_ACCESS_REQUEST_FROM_SING ) )
return ( 0xFFFF );
return ( readsz );
}
#define isITLBufferDone( x ) ( x & 0x18)
#define isITLBufferEmpty( x ) (~x & 0x03)
void iso_transfer_service_from_file_to_ITL( void )
{
static int counter = 0;
static unsigned long offset = 0;
unsigned long pos;
/* */
/* Check, audio device exists */
/* */
if ( NULL == find_device( g_audio_current_target_device_address ) )
{
audio_stop();
return;
}
ITL_fill_from_app_buffer( g_sample_buffer0_ptr, &offset, &counter );
/* */
/* Filling application buffer */
/* */
app_buffer_fill( counter );
}
void ITL_fill_from_app_buffer( short *buff_base, unsigned long *offset_ptr, int *counter_ptr )
{
while ( ITL_fill( (buff_base + *offset_ptr - 4), *counter_ptr % FRAME_PER_BUFFER ) )
{
*offset_ptr += (g_audio_packet[ *counter_ptr % FRAME_PER_BUFFER ]).size >> 1;
(*counter_ptr)++;
if ( *counter_ptr == (FRAME_PER_BUFFER * DOUBLE_BUFFERING * NUM_OF_BUFFER_UNITS) )
{
*counter_ptr = 0;
*offset_ptr = 0;
}
}
}
unsigned char ITL_fill( short *buff, int index )
{
unsigned char ITL_filling_size;
unsigned short interr_mask;
ITL_filling_size = (g_audio_packet[ index ]).size + PTD_HEADER_SIZE + g_ITL_test_value;
/* */
/* Clear ITL Done&Full flag */
/* */
if ( 0 != isITLBufferDone( read_register16( Com16_HcBufferStatus ) ) )
{
write_register16( Com16_HcTransferCounter, 2 ); // It just clears the Full&Done flag
read_register16( Com16_HcITLBufferPort );
}
/* */
/* Write data into ITL */
/* */
if ( isITLBufferEmpty( read_register16( Com16_HcBufferStatus ) ) )
{
*((long *)(buff + 0)) = *(long *)(&((g_audio_packet[ index ].iso_header_ptr)[ 0 ])); // copy PTD header
*((long *)(buff + 2)) = *(long *)(&((g_audio_packet[ index ].iso_header_ptr)[ 2 ])); // total 8 bytes.
#ifdef Use_DMA_TEST
write_register16( Com16_HcuPInterrupt, 0x4 );
dma_start( DMA_write, BUFFER_SELECT_ITL, (unsigned char *)buff, ITL_filling_size );
#else
write_register16( Com16_HcuPInterrupt, (interr_mask = read_register16( Com16_HcuPInterrupt )) & ~0x04 );
write_register16( Com16_HcTransferCounter, ITL_filling_size );
write_register_burst_char( Com16_HcITLBufferPort, (unsigned char *)buff, ITL_filling_size );
write_register16( Com16_HcuPInterrupt, interr_mask | 0x04 );
#endif // end of Use_DMA_TEST
}
else
{
return ( 0 );
}
return ( ITL_filling_size );
}
void app_buffer_fill( int counter )
{
short *read_target_buffer;
int file_access_reserve_timing;
unsigned int read_size;
unsigned long i;
static unsigned char retry = 0;
if ( (counter == file_access_reserve_timing) || (counter == (FRAME_PER_BUFFER * NUM_OF_BUFFER_UNITS) + file_access_reserve_timing) )
{
fileaccess_reserve();
return;
}
else if ( retry || (counter == APPL_BUFFER_FILLING_OFFSET) || (counter == (FRAME_PER_BUFFER * NUM_OF_BUFFER_UNITS) + APPL_BUFFER_FILLING_OFFSET) )
{
if ( counter == APPL_BUFFER_FILLING_OFFSET ) // select target buffer
read_target_buffer = g_sample_buffer1_ptr;
else
read_target_buffer = g_sample_buffer0_ptr;
#ifdef AsyncBuffFill
g_file_load_target_ptr = read_target_buffer; // initiate asynchronus read (This works for FILE source only)
#else
read_size = (*g_buffer_fill_method)( (unsigned char *)read_target_buffer );
if ( read_size == 0xFFFF )
{
fileaccess_reserve();
retry = 1;
return;
}
else if ( read_size == 0 )
{
g_cnt_iso_quit++;
}
retry = 0;
if ( read_size != SINGLE_BUFFER_SIZE__SHORT )
for ( i = read_size; i < SINGLE_BUFFER_SIZE__SHORT; i++ )
*(read_target_buffer + i) = 0;
if ( g_cnt_iso_quit == 3 )
audio_stop();
#endif // end of AsyncBuffFill
}
}
void asynchronus_iso_buffer_fill( void )
{
#ifdef AsyncBuffFill
#define STEPSIZE 128
static unsigned char quit_count = 0;
unsigned long read_size = 0;
unsigned long i;
if ( g_file_load_target_ptr == NULL )
return;
//mprintf( LIGHTGREEN, CONTINUE, "****\r\n" );
_dos_read( g_file_handle, (unsigned char *)g_file_load_target_ptr, SINGLE_BUFFER_SIZE__BYTES, &read_size );
if ( read_size == 0 )
quit_count++;
if ( read_size != SINGLE_BUFFER_SIZE__SHORT )
for ( i = read_size; i < SINGLE_BUFFER_SIZE__SHORT; i++ )
*(g_file_load_target_ptr + i) = 0;
if ( quit_count == 3 )
audio_stop();
g_file_load_target_ptr = NULL;
#endif // #ifdef AsyncBuffFill
}
unsigned char dos_read_exclusive( int file_handle, void *buffer_ptr, unsigned len, unsigned *nread, unsigned char flag, unsigned char requester )
{
static unsigned char previous_flag = FILE_ACCESS_FREE;
static unsigned char block_requester = FILE_ACCESS_REQUEST_FROM_NONE;
static unsigned char accessing = 0;
if ( accessing )
return ( FILE_ACCESS_DENIED );
if ( previous_flag == FILE_ACCESS_RESERVE )
if ( block_requester != requester )
return ( FILE_ACCESS_RESERVED );
else
previous_flag = flag;
if ( flag == FILE_ACCESS_RESERVE )
{
previous_flag = flag;
block_requester = requester;
return ( FILE_ACCESS_RESERVED );
}
accessing = 1;
_dos_read( file_handle, buffer_ptr, len, nread );
accessing = 0;
return ( FILE_ACCESS_READ );
}
void fileaccess_reserve( void )
{
dos_read_exclusive( 0, 0, 0, 0, FILE_ACCESS_RESERVE, FILE_ACCESS_REQUEST_FROM_SING );
}
void fileaccess_free( void )
{
dos_read_exclusive( 0, 0, 0, 0, FILE_ACCESS_FREE, FILE_ACCESS_REQUEST_FROM_SING );
}
#if 0
void dump_pakets( unsigned char *b, int size )
{
int i;
size -= 8;
mprintf( LIGHTGREEN, CONTINUE, "size=%d : header > 0x ", size );
for ( i = 0; i < 8; i++)
mprintf( LIGHTGREEN, CONTINUE, " %02X", *(b + i) );
b += 8;
for ( i = 0; i < size; i++)
{
if ( !(i % 16) )
mprintf( LIGHTGREEN, CONTINUE, "\r\n" );
mprintf( LIGHTGREEN, CONTINUE, " %02X", *(b + i) );
}
mprintf( LIGHTGREEN, CONTINUE, "\r\n" );
key_wait();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -