Subversion Repositories Kolibri OS

Rev

Rev 374 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //      System interface for sound.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24. static const char
  25. rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $";
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <stdarg.h>
  30.  
  31. #include <math.h>
  32.  
  33. #include <sys/types.h>
  34.  
  35. #include <fcntl.h>
  36.  
  37. // Timer stuff. Experimental.
  38. #include <time.h>
  39. #include <signal.h>
  40.  
  41. #include "z_zone.h"
  42.  
  43. #include "i_system.h"
  44. #include "i_sound.h"
  45. #include "m_argv.h"
  46. #include "m_misc.h"
  47. #include "w_wad.h"
  48.  
  49. #include "doomdef.h"
  50.  
  51. #include "kolibri.h"
  52. #include "sound.h"
  53.  
  54. // The number of internal mixing channels,
  55. //  the samples calculated for each mixing step,
  56. //  the size of the 16bit, 2 hardware channel (stereo)
  57. //  mixing buffer, and the samplerate of the raw data.
  58.  
  59.  
  60. // Needed for calling the actual sound output.
  61. #define SAMPLECOUNT     1024
  62. #define NUM_CHANNELS    16
  63. // It is 2 for 16bit, and 2 for two channels.
  64. //#define BUFMUL          4
  65. //#define MIXBUFFERSIZE           (SAMPLECOUNT*BUFMUL)
  66.  
  67. #define SAMPLERATE      11025   // Hz
  68. #define SAMPLESIZE      2       // 16bit
  69.  
  70. // The actual lengths of all sound effects.
  71. int             lengths[NUMSFX];
  72.  
  73. // The actual output device.
  74. int     audio_fd;
  75.  
  76. // The global mixing buffer.
  77. // Basically, samples from all active internal channels
  78. //  are modifed and added, and stored in the buffer
  79. //  that is submitted to the audio device.
  80. signed short    *mixbuffer;
  81.  
  82. // The channel step amount...
  83. unsigned int    channelstep[NUM_CHANNELS];
  84. // ... and a 0.16 bit remainder of last step.
  85. unsigned int    channelstepremainder[NUM_CHANNELS];
  86.  
  87.  
  88. // The channel data pointers, start and end.
  89. unsigned char*  channels[NUM_CHANNELS];
  90. unsigned char*  channelsend[NUM_CHANNELS];
  91.  
  92.  
  93. // Time/gametic that the channel started playing,
  94. //  used to determine oldest, which automatically
  95. //  has lowest priority.
  96. // In case number of active sounds exceeds
  97. //  available channels.
  98. int             channelstart[NUM_CHANNELS];
  99.  
  100. // The sound in channel handles,
  101. //  determined on registration,
  102. //  might be used to unregister/stop/modify,
  103. //  currently unused.
  104. int             channelhandles[NUM_CHANNELS];
  105.  
  106. // SFX id of the playing sound effect.
  107. // Used to catch duplicates (like chainsaw).
  108. int             channelids[NUM_CHANNELS];                      
  109.  
  110. // Pitch to stepping lookup, unused.
  111. int             steptable[256];
  112.  
  113. // Volume lookups.
  114. int             vol_lookup[128*256];
  115.  
  116. // Hardware left and right channel volume lookup.
  117. int*            channelleftvol_lookup[NUM_CHANNELS];
  118. int*            channelrightvol_lookup[NUM_CHANNELS];
  119.  
  120.  
  121. //
  122. // This function loads the sound data from the WAD lump,
  123. //  for single sound.
  124. //
  125. void* getsfx (char* sfxname, int* len)
  126. {
  127.   unsigned char*      sfx;
  128.   unsigned char*      paddedsfx;
  129.   int                 i;
  130.   int                 size;
  131.   int                 paddedsize;
  132.   char                name[20];
  133.   int                 sfxlump;
  134.  
  135.    
  136.     // Get the sound data from the WAD, allocate lump
  137.     //  in zone memory.
  138.     sprintf(name, "ds%s", sfxname);
  139.  
  140.     // Now, there is a severe problem with the
  141.     //  sound handling, in it is not (yet/anymore)
  142.     //  gamemode aware. That means, sounds from
  143.     //  DOOM II will be requested even with DOOM
  144.     //  shareware.
  145.     // The sound list is wired into sounds.c,
  146.     //  which sets the external variable.
  147.     // I do not do runtime patches to that
  148.     //  variable. Instead, we will use a
  149.     //  default sound for replacement.
  150.     if ( W_CheckNumForName(name) == -1 )
  151.       sfxlump = W_GetNumForName("dspistol");
  152.     else
  153.       sfxlump = W_GetNumForName(name);
  154.    
  155.     size = W_LumpLength( sfxlump );
  156.  
  157.     // Debug.
  158.     // fprintf( stderr, "." );
  159.     //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
  160.     //       sfxname, sfxlump, size );
  161.     //fflush( stderr );
  162.    
  163.     sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
  164.  
  165.     // Pads the sound effect out to the mixing buffer size.
  166.     // The original realloc would interfere with zone memory.
  167.     paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
  168.  
  169.     // Allocate from zone memory.
  170.     paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 );
  171.     // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
  172.     // This should interfere with zone memory handling,
  173.     //  which does not kick in in the soundserver.
  174.  
  175.     // Now copy and pad.
  176.     memcpy(  paddedsfx, sfx, size );
  177.     for (i=size ; i<paddedsize+8 ; i++)
  178.         paddedsfx[i] = 128;
  179.  
  180.     // Remove the cached lump.
  181.     Z_Free( sfx );
  182.    
  183.     // Preserve padded length.
  184.     *len = paddedsize;
  185.  
  186.     // Return allocated padded data.
  187.     return (void *) (paddedsfx + 8);
  188. }
  189.  
  190. //
  191. // This function adds a sound to the
  192. //  list of currently active sounds,
  193. //  which is maintained as a given number
  194. //  (eight, usually) of internal channels.
  195. // Returns a handle.
  196. //
  197.  
  198. static unsigned short   handlenums = 0;
  199.  
  200. int addsfx(int sfxid, int volume, int step, int seperation)
  201. {
  202.  
  203.     int         i;
  204.     int         rc = -1;
  205.    
  206.     int         oldest = gametic;
  207.     int         oldestnum = 0;
  208.     int         slot;
  209.  
  210.     int         rightvol;
  211.     int         leftvol;
  212.  
  213.     // Chainsaw troubles.
  214.     // Play these sound effects only one at a time.
  215.     if ( sfxid == sfx_sawup
  216.          || sfxid == sfx_sawidl
  217.          || sfxid == sfx_sawful
  218.          || sfxid == sfx_sawhit
  219.          || sfxid == sfx_stnmov
  220.          || sfxid == sfx_pistol  )
  221.     {
  222.         // Loop all channels, check.
  223.         for (i=0 ; i<NUM_CHANNELS ; i++)
  224.         {
  225.             // Active, and using the same SFX?
  226.             if ( (channels[i])
  227.                  && (channelids[i] == sfxid) )
  228.             {
  229.                 // Reset.
  230.                 channels[i] = 0;
  231.                 // We are sure that iff,
  232.                 //  there will only be one.
  233.                 break;
  234.             }
  235.         }
  236.     }
  237.  
  238.     // Loop all channels to find oldest SFX.
  239.     for (i=0; (i<NUM_CHANNELS) && (channels[i]); i++)
  240.     {
  241.         if (channelstart[i] < oldest)
  242.         {
  243.             oldestnum = i;
  244.             oldest = channelstart[i];
  245.         }
  246.     }
  247.  
  248.     // Tales from the cryptic.
  249.     // If we found a channel, fine.
  250.     // If not, we simply overwrite the first one, 0.
  251.     // Probably only happens at startup.
  252.     if (i == NUM_CHANNELS)
  253.         slot = oldestnum;
  254.     else
  255.         slot = i;
  256.  
  257.     // Okay, in the less recent channel,
  258.     //  we will handle the new SFX.
  259.     // Set pointer to raw data.
  260.     channels[slot] = (unsigned char *) S_sfx[sfxid].data;
  261.     // Set pointer to end of raw data.
  262.     channelsend[slot] = channels[slot] + lengths[sfxid];
  263.  
  264.     // Reset current handle number, limited to 0..100.
  265.     if (!handlenums)
  266.         handlenums = 100;
  267.  
  268.     // Assign current handle number.
  269.     // Preserved so sounds could be stopped (unused).
  270.     channelhandles[slot] = rc = handlenums++;
  271.  
  272.     channelstep[slot] = step;
  273.  
  274.     channelstepremainder[slot] = 0;
  275.     // Should be gametic, I presume.
  276.     channelstart[slot] = gametic;
  277.  
  278.     // Separation, that is, orientation/stereo.
  279.     //  range is: 1 - 256
  280.     seperation += 1;
  281.  
  282.     volume *=7;
  283.     // Per left/right channel.
  284.     //  x^2 seperation,
  285.     //  adjust volume properly.
  286.     leftvol =
  287.         volume - ((volume*seperation*seperation) >> 16); ///(256*256);
  288.     seperation = seperation - 257;
  289.     rightvol =
  290.         volume - ((volume*seperation*seperation) >> 16);        
  291.  
  292.     // Sanity check, clamp volume.
  293.     if (rightvol < 0 || rightvol > 127)
  294.     {
  295.         printf("rightvol out of bounds\n\r");
  296.         rightvol = 0;
  297.  
  298.     }
  299.    
  300.     if (leftvol < 0 || leftvol > 127)
  301.     {
  302.         printf("leftvol out of bounds\n\r");
  303.         leftvol=0;
  304.     }
  305.    
  306.     // Get the proper lookup table piece
  307.     //  for this volume level???
  308.     channelleftvol_lookup[slot] = &vol_lookup[leftvol*256];
  309.     channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
  310.  
  311.     // Preserve sound SFX id,
  312.     //  e.g. for avoiding duplicates of chainsaw.
  313.     channelids[slot] = sfxid;
  314.  
  315.     // You tell me.
  316.     return rc;
  317. }
  318.  
  319. //
  320. // SFX API
  321. // Note: this was called by S_Init.
  322. // However, whatever they did in the
  323. // old DPMS based DOS version, this
  324. // were simply dummies in the Linux
  325. // version.
  326. // See soundserver initdata().
  327. //
  328. void I_SetChannels()
  329. {
  330.   // Init internal lookups (raw data, mixing buffer, channels).
  331.   // This function sets up internal lookups used during
  332.   //  the mixing process.
  333.   int           i;
  334.   int           j;
  335.    
  336.   int*  steptablemid = steptable + 128;
  337.  
  338.   // Okay, reset internal mixing channels to zero.
  339.   for (i=0; i<NUM_CHANNELS; i++)
  340.   {
  341.     channels[i] = 0;
  342.   }
  343.  
  344.   for (i=-128 ; i<128 ; i++)
  345.     steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
  346.  
  347.   // Generates volume lookup tables
  348.   //  which also turn the unsigned samples
  349.   //  into signed samples.
  350.   for (i=0 ; i<128 ; i++)
  351.     for (j=0 ; j<256 ; j++)
  352.       vol_lookup[i*256+j] = (i*(j-128)*256)/127;
  353. }      
  354.  
  355.  
  356. void I_SetSfxVolume(int volume)
  357. {
  358.   // Identical to DOS.
  359.   // Basically, this should propagate
  360.   //  the menu/config file setting
  361.   //  to the state variable used in
  362.   //  the mixing.
  363.   snd_SfxVolume = volume;
  364. }
  365.  
  366. // MUSIC API - dummy. Some code from DOS version.
  367. void I_SetMusicVolume(int volume)
  368. {
  369.   // Internal state variable.
  370.   snd_MusicVolume = volume;
  371. }
  372.  
  373.  
  374. //
  375. // Retrieve the raw data lump index
  376. //  for a given SFX name.
  377. //
  378. int I_GetSfxLumpNum(sfxinfo_t* sfx)
  379. {
  380.     char namebuf[9];
  381.     sprintf(namebuf, "ds%s", sfx->name);
  382.     return W_GetNumForName(namebuf);
  383. }
  384.  
  385. //
  386. // Starting a sound means adding it
  387. //  to the current list of active sounds
  388. //  in the internal channels.
  389. // As the SFX info struct contains
  390. //  e.g. a pointer to the raw data,
  391. //  it is ignored.
  392. // As our sound handling does not handle
  393. //  priority, it is ignored.
  394. // Pitching (that is, increased speed of playback)
  395. //
  396. int I_StartSound(int id, int vol, int sep,
  397.                  int pitch, int priority )
  398. {
  399.     // Returns a handle (not used).
  400.     id = addsfx( id, vol, steptable[pitch], sep );
  401.     return id;
  402. }
  403.  
  404. void I_StopSound (int handle)
  405. {
  406.   // You need the handle returned by StartSound.
  407.   // Would be looping all channels,
  408.   //  tracking down the handle,
  409.   //  an setting the channel to zero.
  410.  
  411.   // UNUSED.
  412.   handle = 0;
  413. }
  414.  
  415.  
  416. int I_SoundIsPlaying(int handle)
  417. {
  418.     // Ouch.
  419.     return gametic < handle;
  420. }
  421.  
  422. //
  423. // This function loops all active (internal) sound
  424. //  channels, retrieves a given number of samples
  425. //  from the raw sound data, modifies it according
  426. //  to the current (internal) channel parameters,
  427. //  mixes the per channel samples into the global
  428. //  mixbuffer, clamping it to the allowed range,
  429. //  and sets up everything for transferring the
  430. //  contents of the mixbuffer to the (two)
  431. //  hardware channels (left and right, that is).
  432. //
  433. // This function currently supports only 16bit.
  434. //
  435.  
  436. extern SNDBUF hMixBuff;
  437. extern unsigned int mix_offset;
  438. extern int mix_size;
  439.  
  440. void I_UpdateSound( void )
  441. {
  442.  
  443.   // Mix current sound data.
  444.   // Data, from raw sound, for right and left.
  445.   register unsigned int sample;
  446.   register int          dl;
  447.   register int          dr;
  448.  
  449.   // Pointers in global mixbuffer, left, right, end.
  450.   signed short*         leftout;
  451.   signed short*         rightout;
  452. //  signed short*         leftend;
  453.   // Step in mixbuffer, left and right, thus two.
  454.   int                           step;
  455.  
  456.   // Mixing channel index.
  457.   int                           chan;
  458.   int i;
  459.    
  460.     // Left and right channel
  461.     //  are in global mixbuffer, alternating.
  462.     leftout = mixbuffer;
  463.     rightout = mixbuffer+1;
  464.     step = 2;
  465.  
  466.     // Determine end, for left channel only
  467.     //  (right channel is implicit).
  468.   //  leftend = mixbuffer + SAMPLECOUNT*step;
  469.  
  470.     // Mix sounds into the mixing buffer.
  471.     // Loop over step*SAMPLECOUNT,
  472.     //  that is 512 values for two channels.
  473.     for (i=0; i < mix_size/4; i++)
  474.     {
  475.         // Reset left/right value.
  476.         dl = 0;
  477.         dr = 0;
  478.  
  479.         // Love thy L2 chache - made this a loop.
  480.         // Now more channels could be set at compile time
  481.         //  as well. Thus loop those  channels.
  482.        
  483.         for ( chan = 0; chan < NUM_CHANNELS; chan++ )
  484.         {
  485.             // Check channel, if active.
  486.             if (channels[ chan ])
  487.             {
  488.                 // Get the raw data from the channel.
  489.                 sample = *channels[ chan ];
  490.                 // Add left and right part
  491.                 //  for this channel (sound)
  492.                 //  to the current data.
  493.                 // Adjust volume accordingly.
  494.                 dl += channelleftvol_lookup[ chan ][sample];
  495.                 dr += channelrightvol_lookup[ chan ][sample];
  496.        
  497.                 channelstepremainder[ chan ] += channelstep[ chan ];
  498.        
  499.                 channels[ chan ] += channelstepremainder[ chan ] >> 16;
  500.        
  501.                 channelstepremainder[ chan ] &= 65536-1;
  502.  
  503.                 // Check whether we are done.
  504.                 if (channels[ chan ] >= channelsend[ chan ])
  505.                     channels[ chan ] = 0;
  506.             }
  507.         }
  508.        
  509.         // Clamp to range. Left hardware channel.
  510.         // Has been char instead of short.
  511.         // if (dl > 127) *leftout = 127;
  512.         // else if (dl < -128) *leftout = -128;
  513.         // else *leftout = dl;
  514.  
  515.         if (dl > 0x7fff)
  516.             *leftout = 0x7fff;
  517.         else if (dl < -0x8000)
  518.             *leftout = -0x8000;
  519.         else
  520.             *leftout = dl;
  521.  
  522.         // Same for right hardware channel.
  523.         if (dr > 0x7fff)
  524.             *rightout = 0x7fff;
  525.         else if (dr < -0x8000)
  526.             *rightout = -0x8000;
  527.         else
  528.             *rightout = dr;
  529.  
  530.         // Increment current pointers in mixbuffer.
  531.         leftout += step;
  532.         rightout += step;
  533.     }
  534.  
  535.     SetBuffer(hMixBuff,mixbuffer,mix_offset,mix_size);
  536. }
  537.  
  538.  
  539. //
  540. // This would be used to write out the mixbuffer
  541. //  during each game loop update.
  542. // Updates sound buffer and audio device at runtime.
  543. // It is called during Timer interrupt with SNDINTR.
  544. // Mixing now done synchronous, and
  545. //  only output be done asynchronous?
  546. //
  547. //void I_SubmitSound(void)
  548. //{
  549.   // Write it to DSP device.
  550. //  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
  551. //}
  552.  
  553.  
  554. void I_UpdateSoundParams(int handle, int vol, int sep, int pitch)
  555. {
  556.   // I fail too see that this is used.
  557.   // Would be using the handle to identify
  558.   //  on which channel the sound might be active,
  559.   //  and resetting the channel parameters.
  560.  
  561.   // UNUSED.
  562.   handle = vol = sep = pitch = 0;
  563. }
  564.  
  565. extern volatile int sound_state;
  566.  
  567. void I_ShutdownSound(void)
  568. {    
  569.   sound_state=0;
  570.   return;
  571. }
  572.  
  573. void I_InitSound()
  574. { int i;
  575.  
  576.   printf("I_InitSound: ");
  577.  
  578.   for (i=1 ; i<NUMSFX ; i++)
  579.   {
  580.     // Alias? Example is the chaingun sound linked to pistol.
  581.     if (!S_sfx[i].link)
  582.     {
  583.       // Load data from WAD file.
  584.       S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
  585.     }  
  586.     else
  587.     {
  588.       // Previously loaded already?
  589.       S_sfx[i].data = S_sfx[i].link->data;
  590.       lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
  591.     }
  592.   }
  593.  
  594.   printf( " pre-cached all sound data\n");
  595.  
  596.   // Now initialize mixbuffer with zero.
  597. //  for ( i = 0; i< MIXBUFFERSIZE; i++ )
  598.  //   mixbuffer[i] = 0;
  599.  
  600.   // Finished initialization.
  601.   printf("I_InitSound: sound module ready\n");
  602.    
  603. }
  604.  
  605.  
  606. //
  607. // MUSIC API.
  608. // Still no music done.
  609. // Remains. Dummies.
  610. //
  611. void I_InitMusic(void)          { }
  612. void I_ShutdownMusic(void)      { }
  613.  
  614. static int      looping=0;
  615. static int      musicdies=-1;
  616.  
  617. void I_PlaySong(int handle, int looping)
  618. {
  619.   // UNUSED.
  620.   handle = looping = 0;
  621.   musicdies = gametic + TICRATE*30;
  622. }
  623.  
  624. void I_PauseSong (int handle)
  625. {
  626.   // UNUSED.
  627.   handle = 0;
  628. }
  629.  
  630. void I_ResumeSong (int handle)
  631. {
  632.   // UNUSED.
  633.   handle = 0;
  634. }
  635.  
  636. void I_StopSong(int handle)
  637. {
  638.   // UNUSED.
  639.   handle = 0;
  640.  
  641.   looping = 0;
  642.   musicdies = 0;
  643. }
  644.  
  645. void I_UnRegisterSong(int handle)
  646. {
  647.   // UNUSED.
  648.   handle = 0;
  649. }
  650.  
  651. int I_RegisterSong(void* data)
  652. {
  653.   // UNUSED.
  654.   data = NULL;
  655.  
  656.   return 1;
  657. }
  658.  
  659. // Is the song playing?
  660. int I_QrySongPlaying(int handle)
  661. {
  662.   // UNUSED.
  663.   handle = 0;
  664.   return looping || musicdies > gametic;
  665. }
  666.  
  667.  
  668. // Interrupt handler.
  669. void I_HandleSoundTimer( int ignore )
  670. {
  671.    
  672.   // UNUSED, but required.
  673.   ignore = 0;
  674.   return;
  675. }
  676.  
  677.