/[enigma]/enigma/src/sound.cc
ViewVC logotype

Diff of /enigma/src/sound.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by dheck, Sun Jan 19 17:58:33 2003 UTC revision 1.5 by dheck, Thu Jan 23 22:34:19 2003 UTC
# Line 19  Line 19 
19   */   */
20  #include "enigma.hh"  #include "enigma.hh"
21  #include "options.hh"  #include "options.hh"
22    #include "oxyd.hh"
23  #include "sound.hh"  #include "sound.hh"
24  #include "system.hh"  #include "system.hh"
25  #include "SDL.h"  #include "SDL.h"
# Line 114  sound::DisableMusic() Line 115  sound::DisableMusic()
115  }  }
116    
117  static Mix_Chunk *  static Mix_Chunk *
 load_oxyd_sound (const string &name)  
 {  
     string filename = enigma::FindDataFile("sound/" + name + ".snd");  
     if (sysdep::FileExists (filename)) {  
 //         Mix_Chunk *c;  
     }  
     return 0;  
 }  
   
 static Mix_Chunk *  
118  cache_sound(const std::string &name)  cache_sound(const std::string &name)
119  {  {
120      px::Dict<Mix_Chunk*>::iterator i=wav_cache.find(name);      px::Dict<Mix_Chunk*>::iterator i=wav_cache.find(name);
121      if (i == wav_cache.end()) {      if (i == wav_cache.end()) {
122          string filename = enigma::FindDataFile("sound/" + name + ".wav");          string filename = enigma::FindDataFile("sound/" + name + ".wav");
123          Mix_Chunk *ch = Mix_LoadWAV(filename.c_str());          Mix_Chunk *ch = 0;
124    
125            ch = enigma::oxyd::LoadSound(name);
126            if (ch == 0)
127                ch = Mix_LoadWAV(filename.c_str());
128    
129          if (ch != 0)          if (ch != 0)
130              wav_cache.insert(name, ch);              wav_cache.insert(name, ch);
131          else          else
# Line 160  sound::PlaySound (const char *name, cons Line 156  sound::PlaySound (const char *name, cons
156      double range = 100;         // How far can sound travel?      double range = 100;         // How far can sound travel?
157      double volume = 1 - length(v)/range;      double volume = 1 - length(v)/range;
158      if (Mix_Chunk *chunk = cache_sound(name)) {      if (Mix_Chunk *chunk = cache_sound(name)) {
159          int channel = Mix_GroupOldest(-1);          int channel = -1; //Mix_GroupOldest(-1);
160          int mixvol = int(volume * options::SoundVolume * MIX_MAX_VOLUME);          int mixvol = int(volume * options::SoundVolume * MIX_MAX_VOLUME);
161                    
162          Mix_PlayChannel(channel, chunk, 0);          channel = Mix_PlayChannel(channel, chunk, 0);
163          Mix_SetPanning(channel, left, right);          Mix_SetPanning(channel, left, right);
164          Mix_Volume(channel, px::Clamp(mixvol, 0, MIX_MAX_VOLUME));          Mix_Volume(channel, px::Clamp(mixvol, 0, MIX_MAX_VOLUME));
165      }      }
# Line 216  sound::StopMusic() Line 212  sound::StopMusic()
212      current_music = 0;      current_music = 0;
213      current_music_name = "";      current_music_name = "";
214  }  }
215    
216    /* SDL_ConvertAudio is not very good at audio resampling since it is
217       only capable of changing the sound frequency by integer powers of 2
218       (i.e., by a factor of ... 1/4 1/2 1 2 ...).  The sound files used
219       by Oxyd are sampled at 6kHz which we must convert to roughly 22kHz.
220       This function resamples between any two frequencies using simple
221       linear interpolation.  It is not capable of changing the sample
222       format or dealing with more than one channel.
223    */
224    namespace
225    {
226        Sint8 *resample (const Sint8 *data, Uint32 len, int oldfreq, int newfreq, Uint32 *newlen)
227        {
228            assert (data);
229            assert (len>0);
230            assert (oldfreq > 0);
231            assert (newfreq > 0);
232            const int sample_size = 1;    //  8bit sample data
233    
234            double ratio = double(oldfreq)/newfreq;
235            *newlen = int(len/ratio + sample_size);
236            Sint8 *newdata = (Sint8*) malloc (sample_size * (*newlen));
237            if (!newdata)
238                return 0;
239    
240            const Sint8 *src = data;
241            Sint8 *dst = newdata;
242            
243            float srcpos = 0;
244            for (int i=0; i<*newlen; ++i) {
245                int srcidx = static_cast<int>(floor(srcpos));
246                float a2 = srcpos - srcidx;
247                float a1 = 1.0f - a2;
248                dst[i] = static_cast<Sint8> (a1*src[srcidx] + a2*src[srcidx+1]);
249                srcpos += ratio;
250            }
251    
252            return newdata;
253        }
254    }
255    
256    
257    
258    
259    Mix_Chunk *
260    sound::ChunkFromRaw (const Uint8 *buf, Uint32 len,
261                         int sfreq, int sformat, int schannels)
262    {
263        if (!sound_initialized || !buf)
264            return 0;
265    
266        // get destination format
267        int dfreq, dchannels;
268        Uint16 dformat;
269        Mix_QuerySpec (&dfreq, &dformat, &dchannels);
270        enigma::Log << "converting: (" << sfreq <<","<<schannels
271                    << ") to (" << dfreq <<","<<dchannels << endl;
272    
273        // resample
274        Uint32 newlen=0;
275        Uint8 *newbuf = (Uint8*) resample ((Sint8*)buf, len, sfreq, dfreq, &newlen);
276    
277    
278        // convert audio data
279        SDL_AudioCVT cvt;
280        if (!SDL_BuildAudioCVT (&cvt, sformat, schannels, dfreq,
281                                dformat, dchannels, dfreq))
282            return 0;
283        
284        cvt.buf = (Uint8*) malloc(newlen * cvt.len_mult);
285        cvt.len = newlen;
286        memcpy(cvt.buf, newbuf, newlen);
287        free(newbuf);
288    
289        SDL_ConvertAudio(&cvt);
290    
291        Mix_Chunk *chunk = Mix_QuickLoad_RAW(cvt.buf, cvt.len_cvt);
292        chunk->allocated = 1;
293        return chunk;
294    }
295    

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26