LCOV - code coverage report
Current view: top level - src - SoundFX.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 11.4 % 105 12
Test Date: 2026-04-03 02:26:39 Functions: 55.6 % 9 5

            Line data    Source code
       1              : #include <cstdio>
       2              : #include <cstring>
       3              : 
       4              : #include "SoundFX.h"
       5              : 
       6              : // SoundFX()
       7              : //
       8              : // Class constructor.
       9           28 : SoundFX::SoundFX() {
      10           14 :   Buffers = NULL;
      11           14 :   Sources = NULL;
      12           14 :   Num_of_SFX = 0;
      13           28 : }
      14              : 
      15              : // ~SoundFX()
      16              : //
      17              : // Class destructor.
      18           26 : SoundFX::~SoundFX() {
      19           13 :   unload();
      20           26 : }
      21              : 
      22              : // load()
      23              : //
      24              : // Sets up OpenAL and loads all sound effect files into
      25              : // memory from the sounds directory.
      26            0 : void SoundFX::load() {
      27            0 :   if (Buffers != NULL || Sources != NULL) {
      28            0 :     PRINT_ERROR("Sounds already loaded; no sounds will be loaded.\n");
      29            0 :     return;
      30              :   }
      31              : 
      32            0 :   Buffers = NULL;
      33            0 :   Sources = NULL;
      34              : 
      35            0 :   DIR *SFXDir = opendir( "./sounds/" );
      36              : 
      37            0 :   if (SFXDir == NULL) {
      38              :     PRINT_DEBUG_LVL(2, "'sounds' directory not present; no sounds will be loaded.\n");
      39            0 :     return;
      40              :   }
      41              : 
      42              :   dirent *de;
      43            0 :   std::string files[256];
      44              : 
      45            0 :   if (SFXDir != NULL) {
      46            0 :     Num_of_SFX = 0;
      47            0 :     while ((de = readdir(SFXDir)) != NULL) {
      48            0 :       if ( std::strstr( de->d_name, ".ogg" ) ) {
      49            0 :         files[Num_of_SFX] = std::string( de->d_name );
      50            0 :         Num_of_SFX++;
      51            0 :       }
      52              :     }
      53            0 :     closedir( SFXDir );
      54            0 :   }
      55              : 
      56            0 :   if (Num_of_SFX < 1) {
      57              :     PRINT_DEBUG_LVL(2, "No sound files in the ogg format present in 'sounds' directory; no sounds will be loaded.\n");
      58            0 :     return;
      59              :   }
      60              : 
      61              :   // Init buffers and sources.
      62            0 :   Buffers = new ALuint[Num_of_SFX];
      63            0 :   Sources = new ALuint[Num_of_SFX];
      64            0 :   alGenBuffers( Num_of_SFX, Buffers );
      65            0 :   alGenSources( Num_of_SFX, Sources );
      66              :   char Sound_Buffer[BUFFER_SIZE];
      67              : 
      68              :   // Load sound files.
      69              :   char filePath[MAX_PATH_LEN];
      70              : 
      71            0 :   for ( int i = 0; i < Num_of_SFX; i++ ) {
      72              :     // build full path to load //
      73            0 :     strcpy(filePath, "./sounds/");
      74            0 :     strcat(filePath, files[i].c_str());
      75              :     PRINT_DEBUG("Loading sound file '%s'...\n", filePath);
      76              : 
      77            0 :     FILE *Music_File = fopen( filePath, "rb" );
      78              : 
      79            0 :     if (Music_File == NULL) {
      80            0 :       PRINT_ERROR("Could not open sound file: '%s'...\n", filePath);
      81            0 :       continue;
      82              :     }
      83              : 
      84              :     OggVorbis_File Ogg_File;
      85            0 :     ov_open( Music_File, &Ogg_File, NULL, 0 );
      86              : 
      87              :     // Get format infomation from the info struct.
      88              :     ALenum Format;
      89            0 :     vorbis_info *Ogg_Info = ov_info( &Ogg_File, -1 );
      90              : 
      91            0 :     if ( Ogg_Info->channels == 1 )
      92            0 :       Format = AL_FORMAT_MONO16;
      93              :     else
      94            0 :       Format = AL_FORMAT_STEREO16;
      95              : 
      96              :     // Fill sound buffers.
      97            0 :     int Size = 0;
      98            0 :     int Section = 0;
      99            0 :     while ( Size < BUFFER_SIZE ) {
     100            0 :       int Bytes = ov_read(
     101              :         &Ogg_File,
     102            0 :         Sound_Buffer + Size,
     103            0 :         BUFFER_SIZE - Size,
     104              :         0, 2, 1, &Section
     105              :       );
     106              : 
     107            0 :       if (Bytes == 0)
     108            0 :         break;
     109              : 
     110            0 :       Size += Bytes;
     111              :     }
     112            0 :     alBufferData( Buffers[i], Format, Sound_Buffer, Size, Ogg_Info->rate );
     113              : 
     114            0 :     ALenum errorCode = alGetError();
     115            0 :     if (errorCode != AL_NO_ERROR)
     116            0 :       PRINT_ERROR("Could not load sound buffer data; AL error code: '%d'.\n", errorCode);
     117              : 
     118            0 :     File_Hash[ files[i] ] = i;  // Create name to index map.
     119            0 :     SetSFX( files[i], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, AL_FALSE );
     120              : 
     121            0 :     ov_clear(&Ogg_File);
     122            0 :   }
     123              : 
     124            0 :   SetSFXListener( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f );
     125            0 : }
     126              : 
     127              : // unload()
     128              : //
     129              : // Cleans up OpenAL buffer information.
     130           26 : void SoundFX::unload() {
     131              :   PRINT_DEBUG("Cleaning-up sounds...\n");
     132           26 :   if (Buffers != NULL) {
     133            0 :     alDeleteBuffers( Num_of_SFX, Buffers );
     134            0 :     delete[] Buffers;
     135            0 :     Buffers = NULL;
     136            0 :   }
     137              : 
     138           26 :   if (Sources != NULL) {
     139            0 :     alDeleteSources( Num_of_SFX, Sources );
     140            0 :     delete[] Sources;
     141            0 :     Sources = NULL;
     142            0 :   }
     143              : 
     144              :   PRINT_DEBUG("Clean-up complete.\n");
     145           26 : }
     146              : 
     147              : // PlaySFX()
     148              : //
     149              : // Plays a specified sound file.  Accepts a file name (not the complete path).
     150            0 : void SoundFX::PlaySFX( const std::string &sfx ) {
     151            0 :   if (Sources == NULL)
     152            0 :     return;
     153              : 
     154              :   PRINT_DEBUG_LVL(1, "Playing sound (%s)\n", sfx.c_str());
     155            0 :   alSourcePlay( Sources[ File_Hash[sfx] ] );
     156              : 
     157            0 :   ALenum errorCode = alGetError();
     158            0 :   if (errorCode != AL_NO_ERROR)
     159            0 :     PRINT_ERROR("Could not play sound; AL error code: '%d'.\n", errorCode);
     160            0 : }
     161              : 
     162              : // SetSFX
     163              : //
     164              : // Sets the location, velocity, and repeat bit for a given file name.  Takes
     165              : // eight parameters: The name of the wav file; X, Y, and Z locational
     166              : // coordinates; X, Y, and Z velocity values; and a boolean representing whether
     167              : // or not the sound should be looped.
     168            0 : void SoundFX::SetSFX(
     169              :     const std::string &sfx,
     170              :     const ALfloat &PosX, const ALfloat &PosY, const ALfloat &PosZ,
     171              :     const ALfloat &VelX, const ALfloat &VelY, const ALfloat &VelZ,
     172              :     const ALboolean &repeat
     173              : ) {
     174            0 :   if (Buffers == NULL || Sources == NULL)
     175            0 :     return;
     176              : 
     177            0 :   ALfloat SourcePos[3] = { PosX, PosY, PosZ };
     178            0 :   ALfloat SourceVel[3] = { VelX, VelY, VelZ };
     179            0 :   int index = File_Hash[sfx];
     180              : 
     181            0 :   alSourcei ( Sources[index], AL_BUFFER,   Buffers[index] );
     182            0 :   alSourcef ( Sources[index], AL_PITCH,    1.0f      );
     183            0 :   alSourcef ( Sources[index], AL_GAIN,     1.0f      );
     184            0 :   alSourcefv( Sources[index], AL_POSITION, SourcePos );
     185            0 :   alSourcefv( Sources[index], AL_VELOCITY, SourceVel );
     186            0 :   alSourcei ( Sources[index], AL_LOOPING,  repeat    );
     187            0 : }
     188              : 
     189              : // SetSFXListener()
     190              : //
     191              : // Sets the position and velocity of the listener.  Takes six parameters.  The
     192              : // first three represent the listener's X, Y, and Z position, and the second
     193              : // three represent the relative X, Y, and Z velocity.
     194            0 : void SoundFX::SetSFXListener(
     195              :     const ALfloat &PosX, const ALfloat &PosY, const ALfloat &PosZ,
     196              :     const ALfloat &VelX, const ALfloat &VelY, const ALfloat &VelZ
     197              : ) {
     198            0 :   ALfloat ListenerPos[3] = { PosX, PosY, PosZ };
     199            0 :   ALfloat ListenerVel[3] = { VelX, VelY, VelZ };
     200            0 :   ALfloat ListenerOri[6] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
     201              : 
     202            0 :   alListenerfv( AL_POSITION,    ListenerPos );
     203            0 :   alListenerfv( AL_VELOCITY,    ListenerVel );
     204            0 :   alListenerfv( AL_ORIENTATION, ListenerOri );
     205            0 : }
        

Generated by: LCOV version 2.4-0