// plays an sfx sample void sfx(int index,int pan,bool loop, bool restart) { if(!sfx_init(index)) return; voice_set_playmode(sfx_voice[index],loop?PLAYMODE_LOOP:PLAYMODE_PLAY); voice_set_pan(sfx_voice[index],pan); int pos = voice_get_position(sfx_voice[index]); if(restart) voice_set_position(sfx_voice[index],0); if(pos<=0) voice_start(sfx_voice[index]); }
// start it (in loop mode) if it's not already playing, // otherwise adjust it to play in loop mode -DD void cont_sfx(int index) { if(!sfx_init(index)) { return; } if(voice_get_position(sfx_voice[index])<=0) { voice_set_position(sfx_voice[index],0); voice_set_playmode(sfx_voice[index],PLAYMODE_LOOP); voice_start(sfx_voice[index]); } else { adjust_sfx(index, 128, true); } }
bool JamulSoundPlay(int voice, long pan, long vol, byte playFlags) { // if this copy is in use, can't play it if (voice_get_position(voice) > 0) { if (playFlags & SOUND_CUTOFF) { voice_set_position(voice, 0); // keep going to handle the rest of the stuff } else return FALSE; // can't play if it's playing } // set the pan and volume and start the voice voice_set_volume(voice, vol); voice_set_pan(voice, pan); voice_start(voice); return TRUE; }
void MYWAVE::seek(int pos) { voice_set_position(voice, pos); }
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; short *dout; short *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] ){ #ifdef USE_COMPENS int fin = stream_buffer_max * freq * 2 / fps; #else int fin = stream_buffer_max * len; #endif if( lpWave[channel] ){ destroy_sample( lpWave[channel] ); lpWave[channel] = 0; } if (!(lpWave[channel] = create_sample(16,0,freq,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) { allegro_message("allocate_voice failed !\n"); exit(1); } voice_set_playmode(hVoice[channel],PLAYMODE_LOOP); playing[channel] = 1; /* use front surface */ init_mixing_buff(len); /**** make sound temp. buffer ****/ if (enh_stereo && SamplePan[channel] == PAN_LEFT) dout=(short*) (((char*)lpWave[channel]->data)+len*(MODEB_UPDATE_COUNT+1)); //+len*MODEB_UPDATE_COUNT); else 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; } update_recording(channel,data); 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; saSetVolume(channel,SampleVol[channel]); saSetPan(channel,SamplePan[channel]); voice_set_position(hVoice[channel],0); voice_start(hVoice[channel]); pos_counter[channel] = 0; } else{ int pos = voice_get_position(hVoice[channel]); int th_pos; int count = (enh_stereo && SamplePan[channel] == PAN_LEFT ? MODEB_UPDATE_COUNT + 1 : MODEB_UPDATE_COUNT); // this difference between the theorical position and the actual // position is because clearly the reported position is directly // dependant of when the sound driver updated the voice for the // last time. Luckily the difference is big only when the voice // starts. After starting it gets more or less updated when it // should, depending on external factors too like the cpu load. dout=vout[channel]; th_pos = (dout - ((INT16 *)lpWave[channel]->data)- count*len/2); if (th_pos < 0) th_pos += stream_buffer_max * len/2; // if there is more than count frames between pos and th_pos, then // wait for the voice. if (pos < th_pos) { if (th_pos - pos < count * len/2) { more_stream = -1; // drop next frame } } din = ((signed short*)data); dfin = vend[channel]; // memcpy(dout,din,len); for (i=0; i<len; i+=2){ *(dout++) = *(din++)^0x8000; } update_recording(channel,data); if (dout >=dfin){ dout=(short*) (((char*)lpWave[channel]->data)); } #ifdef DUMP_CHANNELS fwrite( lpWave[channel]->data+len*s_pos, 1, len, stream_out[channel]); #endif vout[channel] = dout; // more than count frames of advance : more stream ! pos -= count*len/2; if (pos > th_pos && pos > 0) { // send more more_stream = 1; } } }
void seek(int pos) { voice_set_position(voice, pos); }
static int allegro_write(SWORD *pbuf, size_t nr) { static int counter; unsigned int i, count; /*unsigned int write_size;*/ counter++; /* XXX: Assumes `nr' is multiple of `fragment_size'. This is always the case with the current implementation. */ count = nr / (fragment_size / sizeof(SWORD)); /* Write one fragment at a time. FIXME: This could be faster. */ for (i = 0; i < count; i++, pbuf += fragment_size / sizeof(SWORD)) { if (!been_suspended) { unsigned int write_end; /* XXX: We do not use module here because we assume we always write full fragments. */ write_end = buffer_offset + fragment_size - 1; /* Block if we are at the position the soundcard is playing. Notice that we also assume that the part of the buffer we are going to lock is small enough to fit in the safe space. */ while (1) { unsigned int pos = sizeof(SWORD) * voice_get_position(voice); unsigned int pos2 = pos + fragment_size; if (pos2 < buffer_len) { if (buffer_offset >= pos2 || write_end < pos) break; } else { pos2 -= buffer_len; if (write_end < pos && buffer_offset >= pos2) break; } } } /* Write fragment. */ { unsigned int j; WORD *p = (WORD *) (buffer->data + buffer_offset); /* XXX: Maybe the SID engine could already produce samples in unsigned format as we need them here? */ for (j = 0; j < fragment_size / sizeof(SWORD); j++) p[j] = pbuf[j] + 0x8000; } buffer_offset += fragment_size; if (buffer_offset >= buffer_len) buffer_offset = 0; if (been_suspended) { been_suspended = 0; voice_set_position(voice, 0); voice_start(voice); } } written_samples += nr; if (written_samples > buffer_len) written_samples = buffer_len; return 0; }
void GoPlaySound(int num, long pan, long vol, byte flags, int priority) { char txt[32]; int i, best, count; // load the sample if it isn't already if (soundbuf[num].sample == NULL) { sprintf(txt, "sound\\snd%03d.wav", num); soundbuf[num].sample = load_sample(txt); if (soundbuf[num].sample == NULL) return; // can't play the sound, it won't load for some reason } priority += vol; // the quieter a sound, the lower the priority if (flags & SND_MAXPRIORITY) priority = MAX_SNDPRIORITY; if (flags & SND_ONE) { for (i = 0; i < MAX_SOUNDS_AT_ONCE; i++) if (playBuffer[i].soundNum == num) { // if you want to cut it off, or it isn't playing, then start anew if ((flags & SND_CUTOFF) || (!(playBuffer[i].flags & SND_PLAYING))) { playBuffer[i].pan = pan; playBuffer[i].vol = vol; playBuffer[i].flags = flags | SND_PLAYING; playBuffer[i].priority = priority; JamulSoundPlay(playBuffer[i].voice, playBuffer[i].pan, playBuffer[i].vol, SOUND_CUTOFF); return; // good job } else return; // can't be played because can't cut it off } // if you fell through to here, it isn't playing, so go ahead as normal } if (flags & SND_FEW) { count = 0; for (i = 0; i < MAX_SOUNDS_AT_ONCE; i++) if (playBuffer[i].soundNum == num && (playBuffer[i].flags & SND_PLAYING)) count++; if (count >= MAX_FEW_SOUNDS) { for (i = 0; i < MAX_SOUNDS_AT_ONCE; i++) if (playBuffer[i].soundNum == num) { if ((flags & SND_CUTOFF) && (playBuffer[i].flags & SND_PLAYING)) { playBuffer[i].pan = pan; playBuffer[i].vol = vol; playBuffer[i].flags = flags | SND_PLAYING; playBuffer[i].priority = priority; JamulSoundPlay(playBuffer[i].voice, playBuffer[i].pan, playBuffer[i].vol, SOUND_CUTOFF); return; // good job } } return; // failed for some reason } } best = -1; for (i = 0; i < MAX_SOUNDS_AT_ONCE; i++) { if (playBuffer[i].soundNum == -1 || (!(playBuffer[i].flags & SND_PLAYING))) { best = i; break; // can't beat that } if ((playBuffer[i].priority < priority) || (playBuffer[i].soundNum == num && (flags & SND_CUTOFF))) { if (best == -1 || playBuffer[i].priority < playBuffer[best].priority) best = i; } } if (best == -1) return; // sound is not worthy to be played if (playBuffer[best].soundNum != num) // if it was already playing that sound, don't waste time { playBuffer[best].soundNum = num; if (playBuffer[best].voice != -1) { deallocate_voice(playBuffer[best].voice); // slash & burn } playBuffer[best].voice = allocate_voice(soundbuf[num].sample); } else { voice_set_position(playBuffer[best].voice, 0); } if (playBuffer[best].voice == -1) return; // can't play it playBuffer[best].priority = priority; playBuffer[best].pan = pan; playBuffer[best].vol = vol; playBuffer[best].flags = flags | SND_PLAYING; JamulSoundPlay(playBuffer[best].voice, playBuffer[best].pan, playBuffer[best].vol, 0); }