📄 sasound.c
字号:
{ SOUND_INFO *sound_src; // games/games.h int ta; sound_src = current_game->sound_list; if(sound_src){ saStopSoundEmulators(); for( ta = 0; ta < SND_CONTROL_MAX; ta++ ){ SndMachine->init[ta] = SOUND_NONE; SndMachine->intf[ta] = NULL; } SndMachine->first = 0; SndMachine->control_max = 0; ta = 0; while(sound_src[ta].interface){ SndMachine->init[ta] = sound_src[ta].type; SndMachine->intf[ta] = sound_src[ta].interface; ta++; } SndMachine->control_max = ta; GameSound = 1; }}/******************************************//* destroy sound *//******************************************/void saDestroyChannel( int chan ){ if( lpWave[chan] ){ voice_stop(hVoice[chan]); destroy_sample( lpWave[chan] ); lpWave[chan] = 0; playing[chan] = 0; }}void saDestroySound( int remove_all_resources ){ int i;#ifdef RAINE_DEBUG print_debug("saDestroySound: Removing SEAL\n");#endif //pause_raine_ym3812(); remove_sound(); if(remove_all_resources){ saStopSoundEmulators(); } for( i = 0; i < NUMVOICES; i++ ){ voice_stop( hVoice[i] );#ifdef DUMP_CHANNELS fclose(stream_out[i]);#endif } remove_sound(); //SndMachine = NULL;#ifdef RAINE_DEBUG print_debug("saDestroySound: OK\n");#endif}void sa_pause_sound(void){ int i; pause_sound = 1; samp_modeb_timer = 0; vbover_err = 0; vbunder_err = 0; //pause_raine_ym3812(); for( i = 0; i < NUMVOICES; i++ ){ voice_stop( hVoice[i] ); }}void sa_unpause_sound(void){ int i; pause_sound = 0; for( i = 0; i < NUMVOICES; i++ ){ streams_init_timers(i); voice_start( hVoice[i] ); }}/******************************************//* buffer check *//******************************************/void saCheckPlayStream( void ){#if 1 return; /* This function was trying to resynchronize streams before. It did not do it the right way. It's useless now !!! */#else int i; // len, rlen; //int pos,pan; int vp, ve; int is_playing = 0; int old_timer = samp_modeb_timer; if( !pause_sound ){ samp_modeb_timer = (samp_modeb_timer+1) % MODEB_FRAME_SIZE; // <60> res = [0..59] vp = samp_modeb_timer / MODEB_UPDATE_COUNT; // <3> res = [0..19] for( i = 0; i < NUMVOICES; i++ ){ // ***** SCAN VOICES if( playing[i] ){ // ***** PROCESS ENABLED VOICE is_playing=1; ve = ventry[i] % MODEB_MASK; // <60/3=20> res = [0..19] if (vp == ve) { // Normal they joined... ventry[i]++; } else if( ve-vp>1) { // The soundcard is late !!! // I am not sure of what to do in this case... // This should not happen !!! // So be it, force the update !!!#ifdef RAINE_DEBUG fprintf(stderr,"soundcard late %d\n",vp-ve);#endif streams_sh_update(); samp_modeb_timer = (samp_modeb_timer+1) % MODEB_FRAME_SIZE; // next return; } else if ( vp > ve && ve>0) { // The soundcard is in advance !!!#ifdef RAINE_DEBUG fprintf(stderr,"soundcard advance vp %d ve %d\n",vp,ve);#endif streams_sh_update(); samp_modeb_timer = old_timer; for( i = 0; i < NUMVOICES; i++ ){ // ***** SCAN VOICES if( playing[i] ){ // ***** PROCESS ENABLED VOICE ventry[i]++; } } return; // !!! } } } // ***** END SCAN VOICES if (!is_playing) { // very rare : the timer was started before any voice // could play... samp_modeb_timer = old_timer; } } // ***** END PLAY SOUND#endif}void resync_voice(int channel) { // Resync violently a voice when it is too much late ! vout[channel] = (short*) (((char*)lpWave[channel]->data)+base_len*2); voice_set_position(hVoice[channel],0);#ifdef RAINE_DEBUG print_ingame(180,"resync\n");#endif }/*******************************************************************************************//*******************************************************************************************//******************************************//* play samples *//******************************************/void saPlayBufferedStreamedSampleBase( int channel, signed char *data, int len, int freq, int volume, int bits , int pan ){ /* This version works at low level, creating a sample, and following its advancement directly in the voice_position... */ int i; unsigned short *dout,*dfin; signed short *din; //fprintf(stderr,"saPlayBuffer %d freq %d bits %d pan %d len %d\n",channel,freq,bits,pan,len); if( audio_sample_rate == 0 || channel >= NUMVOICES ) return; if( SndMachine == NULL ) return; if( !playing[channel] ){ int fin = stream_buffer_max * len; if( lpWave[channel] ){ destroy_sample( lpWave[channel] ); lpWave[channel] = 0; } if (!(lpWave[channel] = create_sample(16,0,audio_sample_rate,fin/2))){ lpWave[channel] = 0; return; } // memset( lpWave[channel]->data, 0, fin ); dout=lpWave[channel]->data; dfin=(short*) (((char*)lpWave[channel]->data)+fin); // Fill the buffer with 0 (signed) in case the soundcards reads what // is after the sample... while (dout < dfin) *(dout++) = 0x8000; vend[channel] = dfin; counter[channel] = 0; hVoice[channel] = allocate_voice( lpWave[channel] ); if (hVoice[channel]<0) { return; } voice_set_playmode(hVoice[channel],PLAYMODE_LOOP); playing[channel] = 1; /* use front surface */ /**** make sound temp. buffer ****/ dout=(short*) (((char*)lpWave[channel]->data)+len*MODEB_UPDATE_COUNT); //+len*MODEB_UPDATE_COUNT); din = ((signed short*)data); // memcpy( dout, din, len ); for (i=0; i<len; i+=2){ *(dout++) = *(din++)^0x8000; } if (dout ==dfin){ dout=(short*) (((char*)lpWave[channel]->data)); }#ifdef DUMP_CHANNELS fwrite( lpWave[channel]->data+len*MODEB_UPDATE_COUNT, 1, len, stream_out[channel]);#endif vout[channel] = dout; voice_set_volume(hVoice[channel],SampleVol[channel]); voice_set_pan(hVoice[channel],SamplePan[channel]); voice_start(hVoice[channel]); ventry[channel] = 1; } else{ //int s_pos = vchan[channel]%stream_buffer_max; //int theo = len * s_pos/2; //int reel; dout=vout[channel]; din = ((signed short*)data); dfin = vend[channel]; // memcpy(dout,din,len); for (i=0; i<len; i+=2){ *(dout++) = *(din++)^0x8000; } if (dout ==dfin){ dout=(short*) (((char*)lpWave[channel]->data)); counter[channel] = MODEB_UPDATE_COUNT+2; //in 3-1=2 frames, resync } if (counter[channel]) { if (!(--counter[channel])) { voice_set_position(hVoice[channel],0); } } #ifdef DUMP_CHANNELS fwrite( lpWave[channel]->data+len*s_pos, 1, len, stream_out[channel]);#endif vout[channel] = dout; }}#ifdef USE_8BITS/******************************************//* play samples *//******************************************/void saPlayStreamedSampleBase( int channel, signed char *data, int len, int freq, int volume, int bits , int pan ){ // This one should leave most of the sync work to allegro int pos; void *buff; // position in the stream unsigned short *dout; signed short *din; int i; if (bits == 8) { fprintf(stderr,"error: Can't play 8 bits\n"); // Just because I don't want to bother with this now. return; } if( audio_sample_rate == 0 || channel >= NUMVOICES ) return; if( SndMachine == NULL ) return; if( !playing[channel] ){ if( stream[channel] ){ stop_audio_stream(stream[channel]); free_audio_stream_buffer(stream[channel]); stream[channel] = NULL; } if (!(stream[channel] = play_audio_stream(len,bits,0,freq,volume,pan))){ return; } playing[channel] = 1; /* use front surface */ vchan[channel] = 1; ventry[channel] = 1; // Wait for the buffer to be ready... while (!(buff = get_audio_stream_buffer(stream[channel]))); //print_debug("first stream entry. [%d:%d:%d:%d]\n", channel, len, freq, volume ); } if (!(buff = get_audio_stream_buffer(stream[channel]))) { fprintf(stderr,"init stream impossible : buffer NULL\n"); return; } // fprintf(stderr,"len memcpy : %d\n",len); dout=buff; din = ((signed short*)data); pos = voice_get_position(stream[channel]->voice); for (i=0; i<len; i+=2) *(dout++) = *(din++)^0x8000; //fprintf(stderr,"set chanel vol = %d\n",volume);}#endif/******************************************************************************//* *//* SOUND CHANNEL ALLOCATION *//* *//******************************************************************************/int saGetPlayChannels( int request ){ int ret_value = reserved_channel; reserved_channel += request; return ret_value;}void saResetPlayChannels( void ){ reserved_channel = 0;}/******************************************************************************//* *//* SOUND CARD INFORMATION *//* *//******************************************************************************/static char *sound_name_list[10];char *sound_card_name( int num ){ _DRIVER_INFO *digi; int i; sound_name_list[0] = "Silence"; if (system_driver->digi_drivers) digi = system_driver->digi_drivers(); else digi = _digi_driver_list; for (i=0; digi[i].driver; i++) { sound_name_list[i+1] = ((char*)((DIGI_DRIVER *)digi[i].driver)->name); } RaineSoundCardTotal = i; if (num<i) { return sound_name_list[num]; } else return "???"; }int sound_card_id( int i ){ _DRIVER_INFO *digi; if (!i) return 0; if (system_driver->digi_drivers) digi = system_driver->digi_drivers(); else digi = _digi_driver_list; if (i<RaineSoundCardTotal) { DIGI_DRIVER *driver = digi[i-1].driver; if (driver) { return driver->id; } } return 0;}/******************************************************************************//* *//* VOLUME / PANNING CONTROL *//* *//******************************************************************************/void saInitVolPan( void ){ int i; for( i = 0; i < MAX_STREAM_CHANNELS; i++ ){ SampleVol[i] = VOLUME_MAX; SamplePan[i] = PAN_CENTRE; }}void saSetVolume( int num, int data ){ if (data > VOLUME_MAX) data = VOLUME_MAX; if (SampleVol[num] != data) { SampleVol[num] = data; //fprintf(stderr,"vol %d,%x\n",num,data); voice_set_volume(hVoice[num],data); }}void saSetPan( int num, int data ){ if (data > PAN_RIGHT) data = PAN_RIGHT; if (SamplePan[num] != data) { SamplePan[num] = data; //fprintf(stderr,"pan %d,%x\n",num,data); voice_set_pan(hVoice[num],data); }}void saSetPanMulti( int num, int data ){ int i; for( i = 0; i < stream_joined_channels[num]; i++ ) SamplePan[num + i] = data;}/******************************* END OF FILE **********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -