📄 i_sound_sdl.c
字号:
// Generates volume lookup tables // which also turn the unsigned samples // into signed samples. for (i=0 ; i<128 ; i++) for (j=0 ; j<256 ; j++) { vol_lookup[i*256+j] = (i*(j-128)*256)/127;//fprintf(stderr, "vol_lookup[%d*256+%d] = %d\n", i, j, vol_lookup[i*256+j]); }} void I_SetSfxVolume(int volume){ // Identical to DOS. // Basically, this should propagate // the menu/config file setting // to the state variable used in // the mixing. snd_SfxVolume = volume;}// MUSIC API - dummy. Some code from DOS version.void I_SetMusicVolume(int volume){ // Internal state variable. snd_MusicVolume = volume; // Now set volume on output device. // Whatever( snd_MusciVolume );}//// Retrieve the raw data lump index// for a given SFX name.//int I_GetSfxLumpNum(sfxinfo_t* sfx){ char namebuf[9]; sprintf(namebuf, "ds%s", sfx->name); return W_GetNumForName(namebuf);}//// Starting a sound means adding it// to the current list of active sounds// in the internal channels.// As the SFX info struct contains// e.g. a pointer to the raw data,// it is ignored.// As our sound handling does not handle// priority, it is ignored.// Pitching (that is, increased speed of playback)// is set, but currently not used by mixing.//intI_StartSound( int id, int vol, int sep, int pitch, int priority ){ // UNUSED priority = 0; // Debug. //fprintf( stderr, "starting sound %d", id ); // Returns a handle (not used). SDL_LockAudio(); id = addsfx( id, vol, steptable[pitch], sep ); SDL_UnlockAudio(); // fprintf( stderr, "/handle is %d\n", id ); return id;}void I_StopSound (int handle){ // You need the handle returned by StartSound. // Would be looping all channels, // tracking down the handle, // an setting the channel to zero. // UNUSED. handle = 0;}int I_SoundIsPlaying(int handle){ // Ouch. return gametic < handle;}//// This function loops all active (internal) sound// channels, retrieves a given number of samples// from the raw sound data, modifies it according// to the current (internal) channel parameters,// mixes the per channel samples into the given// mixing buffer, and clamping it to the allowed// range.//// This function currently supports only 16bit.//void I_UpdateSound(void *unused, Uint8 *stream, int len){ // Mix current sound data. // Data, from raw sound, for right and left. register unsigned int sample; register int dl; register int dr; // Pointers in audio stream, left, right, end. signed short* leftout; signed short* rightout; signed short* leftend; // Step in stream, left and right, thus two. int step; // Mixing channel index. int chan; // Left and right channel // are in audio stream, alternating. leftout = (signed short *)stream; rightout = ((signed short *)stream)+1; step = 2; // Determine end, for left channel only // (right channel is implicit). leftend = leftout + SAMPLECOUNT*step; // Mix sounds into the mixing buffer. // Loop over step*SAMPLECOUNT, // that is 512 values for two channels. while (leftout != leftend) { // Reset left/right value. dl = 0; dr = 0; // Love thy L2 chache - made this a loop. // Now more channels could be set at compile time // as well. Thus loop those channels. for ( chan = 0; chan < NUM_CHANNELS; chan++ ) { // Check channel, if active. if (channels[ chan ]) { // Get the raw data from the channel. sample = *channels[ chan ]; // Add left and right part // for this channel (sound) // to the current data. // Adjust volume accordingly. dl += channelleftvol_lookup[ chan ][sample]; dr += channelrightvol_lookup[ chan ][sample]; // Increment index ??? channelstepremainder[ chan ] += channelstep[ chan ]; // MSB is next sample??? channels[ chan ] += channelstepremainder[ chan ] >> 16; // Limit to LSB??? channelstepremainder[ chan ] &= 65536-1; // Check whether we are done. if (channels[ chan ] >= channelsend[ chan ]) channels[ chan ] = 0; } } // Clamp to range. Left hardware channel. // Has been char instead of short. // if (dl > 127) *leftout = 127; // else if (dl < -128) *leftout = -128; // else *leftout = dl; if (dl > 0x7fff) *leftout = 0x7fff; else if (dl < -0x8000) *leftout = -0x8000; else *leftout = dl; // Same for right hardware channel. if (dr > 0x7fff) *rightout = 0x7fff; else if (dr < -0x8000) *rightout = -0x8000; else *rightout = dr; // Increment current pointers in stream leftout += step; rightout += step; }}voidI_UpdateSoundParams( int handle, int vol, int sep, int pitch){ // I fail too see that this is used. // Would be using the handle to identify // on which channel the sound might be active, // and resetting the channel parameters. // UNUSED. handle = vol = sep = pitch = 0;}void I_ShutdownSound(void){ SDL_CloseAudio();}voidI_InitSound(){ SDL_AudioSpec wanted; int i; // Secure and configure sound device first. fprintf( stderr, "I_InitSound: "); // Open the audio device wanted.freq = SAMPLERATE; if ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) { wanted.format = AUDIO_S16MSB; } else { wanted.format = AUDIO_S16LSB; } wanted.channels = 2; wanted.samples = SAMPLECOUNT; wanted.callback = I_UpdateSound; if ( SDL_OpenAudio(&wanted, NULL) < 0 ) { fprintf(stderr, "couldn't open audio with desired format\n"); return; } SAMPLECOUNT = wanted.samples; fprintf(stderr, " configured audio device with %d samples/slice\n", SAMPLECOUNT); // Initialize external data (all sounds) at start, keep static. fprintf( stderr, "I_InitSound: "); for (i=1 ; i<NUMSFX ; i++) { // Alias? Example is the chaingun sound linked to pistol. if (!S_sfx[i].link) { // Load data from WAD file. S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] ); } else { // Previously loaded already? S_sfx[i].data = S_sfx[i].link->data; lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)]; } } fprintf( stderr, " pre-cached all sound data\n"); // Finished initialization. fprintf(stderr, "I_InitSound: sound module ready\n"); SDL_PauseAudio(0);}//// MUSIC API.// Still no music done.// Remains. Dummies.//void I_InitMusic(void) { }void I_ShutdownMusic(void) { }static int looping=0;static int musicdies=-1;void I_PlaySong(int handle, int looping){ // UNUSED. handle = looping = 0; musicdies = gametic + TICRATE*30;}void I_PauseSong (int handle){ // UNUSED. handle = 0;}void I_ResumeSong (int handle){ // UNUSED. handle = 0;}void I_StopSong(int handle){ // UNUSED. handle = 0; looping = 0; musicdies = 0;}void I_UnRegisterSong(int handle){ // UNUSED. handle = 0;}int I_RegisterSong(void* data){ // UNUSED. data = NULL; return 1;}// Is the song playing?int I_QrySongPlaying(int handle){ // UNUSED. handle = 0; return looping || musicdies > gametic;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -