⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i_sound.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
// Pitching (that is, increased speed of playback)
//  is set, but currently not used by mixing.
//
int
I_StartSound
( int		id,
  int		vol,
  int		sep,
  int		pitch,
  int		priority )
{

    if (nosound)
        return -1;

    // Debug.
    //printf( "I_StartSound: starting sound %d\n", id );

    // Returns a handle (not used).
    id = addsfx( id, vol, steptable[pitch], sep );

    // 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 global
//  mixbuffer, clamping it to the allowed range,
//  and sets up everything for transferring the
//  contents of the mixbuffer to the (two)
//  hardware channels (left and right, that is).
//
// This function currently supports only 16bit.
//
void I_UpdateSound( void )
{

  // Mix current sound data.
  // Data, from raw sound, for right and left.
  register unsigned int	sample;
  register int		dl;
  register int		dr;

  // Pointers in global mixbuffer, left, right, end.
  signed short*		leftout;
  signed short*		rightout;
  signed short*		leftend;
  // Step in mixbuffer, left and right, thus two.
  int				step;

  // Mixing channel index.
  int				chan;

    // Left and right channel
    //  are in global mixbuffer, alternating.
   leftout = pmData->MixBuffers[ pmData->FillBuffer].pBuffer;
   rightout = leftout+1;// pmData->BufferParms.ulBufferSize/2;
      // next fill buffer
   pmData->FillBuffer++;
   if (pmData->FillBuffer >= pmData->BufferParms.ulNumBuffers)
       pmData->FillBuffer = 0;
   step = 2;

      // Determine end, for left channel only
      //  (right channel is implicit).
      // ulBufferSize is len in bytes (8 bit), ulBufferSize/2 is 16bit length
   leftend = leftout + pmData->BufferParms.ulBufferSize/2;

    // 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 ])
         {
            //printf( "I_UpdateSound: channel %d active\n", 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;

      //dl <<= 4;
      //dr <<= 4;

      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 mixbuffer.
      leftout += step;
      rightout += step;
/*
         // mono out
      *leftout = (dl+dr)/2;
      leftout++;
      rightout++;
*/
   }

}


//
// This would be used to write out the mixbuffer
//  during each game loop update.
// Updates sound buffer and audio device at runtime.
// It is called during Timer interrupt with SNDINTR.
// Mixing now done synchronous, and
//  only output be done asynchronous?
//
void
I_SubmitSound(void)
{
  // Write it to DSP device.
  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
}



void
I_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)
{
   // Wait till all pending sounds are finished.
   int done = 0;
   int i;

   //added:03-01-98:
   if( !sound_started )
       return;

   // FIXME (below).
   printf( "I_ShutdownSound: NOT finishing pending sounds\n");

   while ( !done )
   {
      for( i=0 ; i<8 && !channels[i] ; i++);

      // FIXME. No proper channel output.
      //if (i==8)
      done=1;
      DosSleep( 100);                      // wait 0.1 sec
   }

   ShutdownDART( pmData);

   // Done.
   sound_started = false;
   return;
}


void I_StartupSound()
{
   int i;

   if (nosound)
      return;

      // init dart audio
   InitDART( pmData);

   // Secure and configure sound device first.

   // Initialize external data (all sounds) at start, keep static.
   printf( "I_InitSound\n");

   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)];
      }
   }

   printf( "I_InitSound: pre-cached all sound data\n");

   // Now initialize mixbuffer with zero.
   for ( i = 0; i< MIXBUFFERSIZE; i++ )
      mixbuffer[i] = 0;

   I_SetChannels();

   // Finished initialization.
   printf( "I_InitSound: sound module ready\n");

   //added:08-01-98:we use a similar startup/shutdown scheme as Allegro.
   I_AddExitFunc(I_ShutdownSound);
   sound_started = true;

}




//
// MUSIC API.
// Still no music done.
// Remains. Dummies.
//
void I_InitMusic(void)
{
   printf( "I_InitMusic\n");

   if (nomusic)
      return;

   // initialisation of midicard by I_StartupSound
   pMus2MidData = (char *)Z_Malloc (MIDBUFFERSIZE,PU_STATIC,NULL);

   I_AddExitFunc(I_ShutdownMusic);
   music_started = true;
}

void I_ShutdownMusic(void)
{
   printf( "I_ShutdownMusic\n");

   if (!music_started)
      return;

   I_StopSong( 0);
   I_UnRegisterSong( 0);

   music_started=false;
}

void I_PlaySong(int handle, int looping)
{
   if (nomusic)
      return;

   printf( "I_PlaySong looping=%d\n", looping);
   PlayMIDI( pmData, looping);
      // need to set volume again, because before midi device was closed
   SetMIDIVolume( pmData, cv_musicvolume.value);
}

void I_PauseSong (int handle)
{
   if (nomusic)
      return;

   PauseMIDI( pmData);
}

void I_ResumeSong (int handle)
{
   if (nomusic)
      return;

   // UNUSED.
   handle = 0;
   ResumeMIDI( pmData);
}

void I_StopSong(int handle)
{
   if (nomusic)
      return;

   // UNUSED.
   ShutdownMIDI( pmData);
}

void I_UnRegisterSong(int handle)
{
   if (nomusic)
      return;

   // UNUSED.
   handle = 0;
   printf( "I_UnRegisterSong\n");
      // remove files
   unlink( "doom.mid");
   unlink( "doom.mus");
}

// ---------------
// I_SaveMemToFile
// Save as much as iLength bytes starting at pData, to
// a new file of given name. The file is overwritten if it is present.
// ---------------
void I_SaveMemToFile (unsigned char* pData, unsigned long iLength, char* sFileName)
{
    int     fileHandle;

    fileHandle = open( sFileName, O_CREAT | O_BINARY | O_TRUNC | O_WRONLY, 
                       S_IWRITE);
    if (fileHandle == -1)
    {
        I_Error ("SaveMemToFile");
    }
    write( fileHandle, pData, iLength);
    close( fileHandle);
}

int I_RegisterSong(void* data, int len)
{
    int             iErrorCode;
    char*           pMidiFileData = NULL;       // MIDI music buffer to be played or NULL
    int             iMus2MidSize;               // size of Midi output data
   FILE* blah;

    if (nomusic)
        return 1;
/*
#ifdef DEBUGMIDISTREAM
    CONS_Printf("I_RegisterSong: \n");
#endif
    if (!memcmp(data,"MUS",3))
    {
        // convert mus to mid with a wonderful function
        // thanks to S.Bacquet for the sources of qmus2mid
        // convert mus to mid and load it in memory
        if((iErrorCode = qmus2mid((char *)data,pMus2MidData,89,64,0,len,MIDBUFFERSIZE,
                                   &iMus2MidSize))!=0)
        {
            CONS_Printf("Cannot convert mus to mid, converterror :%d\n",iErrorCode);
            return 0;
        }
        pMidiFileData = pMus2MidData;
    }
    else
    // support mid file in WAD !!! (no conversion needed)
    if (!memcmp(data,"MThd",4))
    {
        pMidiFileData = data;
    }
    else
    {
        CONS_Printf ("Music lump is not MID or MUS music format\n");
        return 0;
    }

    if (pMidiFileData == NULL)
    {
        CONS_Printf ("Not a valid MIDI file : %d\n",iErrorCode);
        return 0;
    }
#ifdef DEBUGMIDISTREAM //EVENMORE
    else
    {
        I_SaveMemToFile (pMidiFileData, iMus2MidSize, "c:/temp/debug.mid");
    }
#endif
    I_SaveMemToFile (pMidiFileData, iMus2MidSize, "doom.mid");
*/

    I_SaveMemToFile (data, len, "doom.mus");
    qmus2mid( "doom.mus", "doom.mid", 0, 89,64,1);

    OpenMIDI( pmData);

    return 1;
}

// Is the song playing?
int I_QrySongPlaying(int handle)
{
   // UNUSED.
   handle = 0;
   printf( "I_QrySongPlaying\n");

   return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -