?? smp16bit.c
字號:
/******************************************************************************//* *//* 16-BIT SAMPLE PLAYBACK (odd samples - nichibutsu dac, cabal adpcm) *//* *//******************************************************************************/#include "raine.h"#include "sasound.h"#include "smp16bit.h"#ifdef RAINE_DEBUG#include "debug.h"#include "ingame.h"#endif/*todo:- different sample rate for each sample, maybe also volume and panning?*/static DEF_INLINE int aLimit( int val, int max, int min ){ if ( val > max ) val = max; else if ( val < min ) val = min; return val;}static int ad_sample;static int ad_index;static int ad_index_table[8] ={ -1, -1, -1, -1, 2, 4, 6, 8};static int ad_offset_table[49] ={ 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0029, 0x002d, 0x0032, 0x0037, 0x003c, 0x0042, 0x0049, 0x0050, 0x0058, 0x0061, 0x006b, 0x0076, 0x0082, 0x008f, 0x009d, 0x00ad, 0x00be, 0x00d1, 0x00e6, 0x00fd, 0x0117, 0x0133, 0x0151, 0x0173, 0x0198, 0x01c1, 0x01ee, 0x0220, 0x0256, 0x0292, 0x02d4, 0x031c, 0x036c, 0x03c3, 0x0424, 0x048e, 0x0502, 0x0583, 0x0610};static void ad_decode(int ad_code){ int ad_base; int ad_offset; ad_base = ad_offset_table[ad_index]; ad_offset = ad_base/8; if( ad_code&0x01 ) ad_offset += ad_base>>2; if( ad_code&0x02 ) ad_offset += ad_base>>1; if( ad_code&0x04 ) ad_offset += ad_base; if( ad_code&0x08 ) ad_offset = 0 - ad_offset; ad_sample = aLimit( ad_sample + ad_offset , 0x7FF, -0x800 ); ad_index = aLimit( ad_index + ad_index_table[ad_code&7], 48, 0 );}// Type 0 - adpcm (cabal)void decode_sample_adpcm(UINT8 *src, UINT32 size, UINT16 *dest, int volume){ UINT32 ta; ad_sample = 0; ad_index = 0; for(ta=0;ta<size;ta++){ ad_decode((src[ta]>>4)&0x0F); *dest++ = (INT16) aLimit((((ad_sample * 16) * volume)/16), 0x7FFF, -0x8000); ad_decode((src[ta]>>0)&0x0F); *dest++ = (INT16) aLimit((((ad_sample * 16) * volume)/16), 0x7FFF, -0x8000); }}// Type 1 - 8bit dac (nichibutsu)void decode_sample_8bit(UINT8 *src, UINT32 size, UINT16 *dest, int volume){ UINT32 ta; ad_sample = 0; ad_index = 0; for(ta=0;ta<size;ta++){ *dest++ = (INT16) aLimit(((((src[ta]-0x80) * 256) * volume)/16), 0x7FFF, -0x8000); }}SMP16Rec SMP16_entry[SMP16BF_MAX], *SMP16;static int chip_max;static int sample_len;static int emu_rate;static int stream[SMP16BF_MAX];#define UPDATE_SHIFT (8)/**************************************************//* sh start *//**************************************************/int SMP16buffer_sh_start( struct SMP16buffer_interface *intf ){ char buf[40]; int ta, i; int rate; SMP16_ROM *rom; SMP16_SAMPLE *sample_decode; rate = audio_sample_rate; chip_max = intf->num; sample_len = rate / 60; emu_rate = sample_len * 60; for( i = 0; i < chip_max; i++ ){ SMP16_entry[i].rate = intf->sample_rate[i]; SMP16_entry[i].command = -1; SMP16_entry[i].add = (UINT32) (((float)intf->sample_rate[i] / (float)emu_rate)*(1<<UPDATE_SHIFT)); SMP16_entry[i].offset = (UINT32) -1; SMP16_entry[i].req_len = 0; SMP16_entry[i].req_buf = NULL; // rom bank base pointers rom = intf->rom[i]; // Calculate sample count ta=0; while(rom[ta].data){ ta++; } SMP16_entry[i].samples = ta; // Make decode rom data sample_decode = (SMP16_SAMPLE *) malloc(SMP16_entry[i].samples * sizeof(SMP16_SAMPLE)); SMP16_entry[i].sample_decode = sample_decode; // malloc error if(!sample_decode) SMP16_entry[i].samples = 0; // Decode them for(ta = 0; (UINT32)ta < SMP16_entry[i].samples; ta++){ switch(rom[ta].type){ case 0x00: sample_decode[ta].len = (UINT32) (rom[ta].size * 2); sample_decode[ta].data = (INT16 *) malloc(sample_decode[ta].len * 2); decode_sample_adpcm(rom[ta].data, rom[ta].size, sample_decode[ta].data, 24); break; case 0x01: sample_decode[ta].len = (UINT32) (rom[ta].size * 1); sample_decode[ta].data = (INT16 *) malloc(sample_decode[ta].len * 2); decode_sample_8bit(rom[ta].data, rom[ta].size, sample_decode[ta].data, 24); break; } } // Stream setup sprintf( buf, "SMP16 #%d", i ); stream[i] = stream_init( buf, emu_rate, 16, i, SMP16buffer_UpdateOne ); } return 0;}/**************************************************//* sh end *//**************************************************/void SMP16buffer_sh_stop( void ){ int ta,i; SMP16_SAMPLE *sample_decode; for(i = 0; i < chip_max; i++){ sample_decode = SMP16_entry[i].sample_decode; for(ta = 0; (UINT32)ta < SMP16_entry[i].samples; ta++){ if(sample_decode[ta].data) free(sample_decode[ta].data); } } chip_max = 0;}/**************************************************//* request *//**************************************************/void SMP16buffer_request( int num, int code ){ SMP16_SAMPLE *sample_decode; if( num >= chip_max ) return; SMP16 = &SMP16_entry[num]; sample_decode = SMP16->sample_decode; if((sample_decode) && ((UINT32)code < SMP16->samples)){ SMP16->req_buf = (INT16 *) (sample_decode[code].data); SMP16->req_len = (sample_decode[code].len) << UPDATE_SHIFT; SMP16->offset = 0; } else{ SMP16->req_buf = NULL; } if(!(SMP16->req_buf)){ SMP16->offset = (UINT32) -1;#ifdef RAINE_DEBUG print_ingame(120,"Now SMP16(%d) not samp[%02x]", num, code );#endif }}/**************************************************//* read status *//**************************************************/// 0 = not playing// 1 = playingint SMP16buffer_status( int num ){ int ret; if( num >= chip_max ) return 0; ret = 0; SMP16 = &SMP16_entry[num]; if( SMP16->offset != (UINT32) -1 ) ret |= 1; return ret;}/**************************************************//* update *//**************************************************/void SMP16buffer_UpdateOne( int num, void *buffer, int length ){ int data; INT16 *sp; if(!length) return; sp = (INT16 *) buffer; SMP16 = &SMP16_entry[num]; do{ data = 0; if(SMP16->offset != (UINT32) -1){ data += *( SMP16->req_buf + (SMP16->offset >> UPDATE_SHIFT) ); if( (SMP16->offset += SMP16->add) >= SMP16->req_len ) SMP16->offset = (UINT32) -1; } *sp++ = aLimit( data, 32767, -32768 ); }while(--length);}/**************** end of file ****************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -