Beispiel #1
0
bool Source_Sample::LoadWAV(const char* filename)
{
	log_verbose("Source_Sample::LoadWAV(%s)", filename);

	Unload();
	SDL_RWops* rw = SDL_RWFromFile(filename, "rb");
	if (rw == NULL) {
		log_verbose("Error loading %s", filename);
		return false;
	}

	SDL_AudioSpec audiospec;
	memset(&audiospec, 0, sizeof(audiospec));
	SDL_AudioSpec* spec = SDL_LoadWAV_RW(rw, false, &audiospec, &data, (Uint32*)&length);
	SDL_RWclose(rw);

	if (spec != NULL) {
		format.freq = spec->freq;
		format.format = spec->format;
		format.channels = spec->channels;
		issdlwav = true;
	} else {
		log_verbose("Error loading %s, unsupported WAV format", filename);
		return false;
	}

	return true;
}
Beispiel #2
0
SDL_AudioCVT *SOUND_LoadWAV(const char *filename)
{
   SDL_AudioCVT *wavecvt;
   SDL_AudioSpec wavespec, *loaded;
   unsigned char *buf;
   unsigned int len;

   if (!g_fAudioOpened) {
      return NULL;
   }

   wavecvt = (SDL_AudioCVT *)malloc(sizeof(SDL_AudioCVT));
   if (wavecvt == NULL) {
      return NULL;
   }

   loaded = SDL_LoadWAV_RW(SDL_RWFromFile(filename, "rb"), 1, &wavespec, &buf, &len);
   if (loaded == NULL) {
      free(wavecvt);
      return NULL;
   }

   // Build the audio converter and create conversion buffers
   if (SDL_BuildAudioCVT(wavecvt, wavespec.format, wavespec.channels, wavespec.freq,
      audio_spec.format, audio_spec.channels, audio_spec.freq) < 0) {
      SDL_FreeWAV(buf);
      free(wavecvt);
      return NULL;
   }
   int samplesize = ((wavespec.format & 0xFF) / 8) * wavespec.channels;
   wavecvt->len = len & ~(samplesize - 1);
   wavecvt->buf = (unsigned char *)malloc(wavecvt->len * wavecvt->len_mult);
   if (wavecvt->buf == NULL) {
      SDL_FreeWAV(buf);
      free(wavecvt);
      return NULL;
   }
   memcpy(wavecvt->buf, buf, len);
   SDL_FreeWAV(buf);

   // Run the audio converter
   if (SDL_ConvertAudio(wavecvt) < 0) {
      free(wavecvt->buf);
      free(wavecvt);
      return NULL;
   }

   return wavecvt;
}
Beispiel #3
0
/**
 * @brief Loads a wav file from the rw if possible.
 *
 * @note Closes the rw.
 *
 *    @param snd Sound to load wav into.
 *    @param rw Data for the wave.
 */
static int sound_al_loadWav( alSound *snd, SDL_RWops *rw )
{
   SDL_AudioSpec wav_spec;
   Uint32 wav_length;
   Uint8 *wav_buffer;
   ALenum format;

   SDL_RWseek( rw, 0, SEEK_SET );

   /* Load WAV. */
   if (SDL_LoadWAV_RW( rw, 0, &wav_spec, &wav_buffer, &wav_length) == NULL) {
      WARN(_("SDL_LoadWav_RW failed: %s"), SDL_GetError());
      return -1;
   }

   /* Handle format. */
   switch (wav_spec.format) {
      case AUDIO_U8:
      case AUDIO_S8:
         format = (wav_spec.channels==1) ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8;
         break;
      case AUDIO_U16LSB:
      case AUDIO_S16LSB:
         format = (wav_spec.channels==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
         break;
      case AUDIO_U16MSB:
      case AUDIO_S16MSB:
         WARN( _("Big endian WAVs unsupported!") );
         return -1;
      default:
         WARN( _("Invalid WAV format!") );
         return -1;
   }

   /* Load into openal. */
   soundLock();
   /* Create new buffer. */
   alGenBuffers( 1, &snd->u.al.buf );
   /* Put into the buffer. */
   alBufferData( snd->u.al.buf, format, wav_buffer, wav_length, wav_spec.freq );
   soundUnlock();

   /* Clean up. */
   free( wav_buffer );
   return 0;
}
Beispiel #4
0
void  cargar_sonido ( char *fichero_wav, int identificador ){

	/* Variables locales */

	FILE *fichero;
	SDL_RWops *file;
	char filename[LON_BUFF];
	SDL_AudioSpec wav_spec;
	Uint32 size;
	Uint8 *data;

	/* Generamos buffer, le asignamos un identificador y comprobamos errores */
	alGenBuffers( 1, &buffer[identificador] );
	if ( !alIsBuffer ( buffer[identificador] )){
		log_msj ( "[KO] error al crear los buffers\n");
	}

	/* Establecemos donde estara situado el directorio para los sonidos */
	strcpy(filename, "sonidos");
	strcat(filename, "/");
	strcat(filename, fichero_wav);
	log_msj("[efectos.c] Cargando sonido %s\n", filename);

	/* Cargamos ficheros Wave */
	fichero = abre_fichero(filename, "rb");
	file = SDL_RWFromFP(fichero,0);
	if( SDL_LoadWAV_RW(file,1, &wav_spec,&data,&size)== NULL ){
		log_msj("[KO]Error al cargar %s\n",filename);
		return;
	}
	alBufferData ( buffer[identificador], AL_FORMAT_STEREO16, data, size, wav_spec.freq ); /* Almacenamos en buffer */
	SDL_FreeWAV(data);/*Liberamos*/
	fclose(fichero);


	/* Generamos las fuentes de sonido y comprobamos errores */
	alGenSources( 1, &source[identificador] );
	if ( !alIsSource ( source[identificador])){
		log_msj ("[KO] No se pueden crear las fuentes de sonido\n");
	}

	/* Pasamos el archivo wav del buffer a la fuente */
	alSourcei ( source[identificador], AL_BUFFER, buffer[identificador]);

}
Beispiel #5
0
void
sound::loadWav(const char * buffer, int length)
{
    puts("sound::loadWav");
#ifdef __USE_OPENAL__
/*
    Yes, I also use SDL.
*/
    SDL_AudioSpec spec;
    ALenum format = NULL;

    if ( SDL_LoadWAV_RW(SDL_RWFromMem((char *)buffer, length), 0, &spec, &buf, &(this->length)) == NULL )
    {
        fprintf(stderr, "Could not open thingie from memory: %s\n", SDL_GetError());
        return;
    }

    printf("this->buffer: %d\n", this->buffer);
    alGenBuffers(1, &(this->buffer));
    printf("this->buffer: %d\n", this->buffer);

    switch (spec.format) {
        case AUDIO_U8:
        case AUDIO_S8:
            format = (spec.channels==1) ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8;
            break;
        case AUDIO_U16LSB:
        case AUDIO_S16LSB:
            format = (spec.channels==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
            break;
    }

    alBufferData(this->buffer, format, buf, this->length, spec.freq);

    printf("format: %d, length: %d, freq: %d\n", format, this->length, spec.freq);
    puts("Uploaded to buffer");
    if ( alGetError() != AL_NO_ERROR) 
        printf("load failed wat : %s\n", alGetError());
    printf("this->buffer: %d\n", this->buffer);

#endif /* __USE_OPENAL__ */
}
Beispiel #6
0
bool Sample::Load(const char* filename)
{
	Unload();
	SDL_RWops* rw = SDL_RWFromFile(filename, "rb");
	if (!rw) {
		SDL_RWclose(rw);
		return false;
	}
	SDL_AudioSpec audiospec;
	memset(&audiospec, 0, sizeof(audiospec));
	SDL_AudioSpec* spec = SDL_LoadWAV_RW(rw, false, &audiospec, &data, (Uint32*)&length);
	if (spec != NULL) {
		format.freq = spec->freq;
		format.format = spec->format;
		format.channels = spec->channels;
		issdlwav = true;
	} else {
		return false;
	}
	return true;
}
Beispiel #7
0
/*
 * Load a sound.
 */
sound_t *
syssnd_load(char *name)
{
    sound_t *s;
    SDL_RWops *context;
    SDL_AudioSpec audiospec;

    /* alloc context */
    context = malloc(sizeof(SDL_RWops));
    context->seek = sdlRWops_seek;
    context->read = sdlRWops_read;
    context->write = sdlRWops_write;
    context->close = sdlRWops_close;

    /* open */
    if (sdlRWops_open(context, name) == -1)
        return NULL;

    /* alloc sound */
    s = malloc(sizeof(sound_t));
#ifdef DEBUG
    s->name = malloc(strlen(name) + 1);
    strncpy(s->name, name, strlen(name) + 1);
#endif

    /* read */
    /* second param == 1 -> close source once read */
    if (!SDL_LoadWAV_RW(context, 1, &audiospec, &(s->buf), &(s->len)))
    {
        free(s);
        return NULL;
    }

    s->dispose = FALSE;

    return s;
}
Beispiel #8
0
/* Load a wave file */
Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
{
	Uint32 magic;
	Mix_Chunk *chunk;
	SDL_AudioSpec wavespec, *loaded;
	SDL_AudioCVT wavecvt;
	int samplesize;

	/* rcg06012001 Make sure src is valid */
	if ( ! src ) {
		SDL_SetError("Mix_LoadWAV_RW with NULL src");
		return(NULL);
	}

	/* Make sure audio has been opened */
	if ( ! audio_opened ) {
		SDL_SetError("Audio device hasn't been opened");
		if ( freesrc && src ) {
			SDL_RWclose(src);
		}
		return(NULL);
	}

	/* Allocate the chunk memory */
	chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk));
	if ( chunk == NULL ) {
		SDL_SetError("Out of memory");
		if ( freesrc ) {
			SDL_RWclose(src);
		}
		return(NULL);
	}

	/* Find out what kind of audio file this is */
	magic = SDL_ReadLE32(src);
	/* Seek backwards for compatibility with older loaders */
	SDL_RWseek(src, -(int)sizeof(Uint32), RW_SEEK_CUR);

	switch (magic) {
		case WAVE:
		case RIFF:
			loaded = SDL_LoadWAV_RW(src, freesrc, &wavespec,
					(Uint8 **)&chunk->abuf, &chunk->alen);
			break;
		case FORM:
			loaded = Mix_LoadAIFF_RW(src, freesrc, &wavespec,
					(Uint8 **)&chunk->abuf, &chunk->alen);
			break;
#ifdef OGG_MUSIC
		case OGGS:
			loaded = Mix_LoadOGG_RW(src, freesrc, &wavespec,
					(Uint8 **)&chunk->abuf, &chunk->alen);
			break;
#endif
#ifdef FLAC_MUSIC
		case FLAC:
			loaded = Mix_LoadFLAC_RW(src, freesrc, &wavespec,
					(Uint8 **)&chunk->abuf, &chunk->alen);
			break;
#endif
		case CREA:
			loaded = Mix_LoadVOC_RW(src, freesrc, &wavespec,
					(Uint8 **)&chunk->abuf, &chunk->alen);
			break;
		default:
			SDL_SetError("Unrecognized sound file type");
			if ( freesrc ) {
				SDL_RWclose(src);
			}
			loaded = NULL;
			break;
	}
	if ( !loaded ) {
		/* The individual loaders have closed src if needed */
		SDL_free(chunk);
		return(NULL);
	}

#if 0
	PrintFormat("Audio device", &mixer);
	PrintFormat("-- Wave file", &wavespec);
#endif

	/* Build the audio converter and create conversion buffers */
	if ( wavespec.format != mixer.format ||
		 wavespec.channels != mixer.channels ||
		 wavespec.freq != mixer.freq ) {
		if ( SDL_BuildAudioCVT(&wavecvt,
				wavespec.format, wavespec.channels, wavespec.freq,
				mixer.format, mixer.channels, mixer.freq) < 0 ) {
			SDL_free(chunk->abuf);
			SDL_free(chunk);
			return(NULL);
		}
		samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels;
		wavecvt.len = chunk->alen & ~(samplesize-1);
		wavecvt.buf = (Uint8 *)SDL_calloc(1, wavecvt.len*wavecvt.len_mult);
		if ( wavecvt.buf == NULL ) {
			SDL_SetError("Out of memory");
			SDL_free(chunk->abuf);
			SDL_free(chunk);
			return(NULL);
		}
		memcpy(wavecvt.buf, chunk->abuf, chunk->alen);
		SDL_free(chunk->abuf);

		/* Run the audio converter */
		if ( SDL_ConvertAudio(&wavecvt) < 0 ) {
			SDL_free(wavecvt.buf);
			SDL_free(chunk);
			return(NULL);
		}

		chunk->abuf = wavecvt.buf;
		chunk->alen = wavecvt.len_cvt;
	}

	chunk->allocated = 1;
	chunk->volume = MIX_MAX_VOLUME;

	return(chunk);
}
Beispiel #9
0
	static int lua_Mix_Load(State & state){
		Stack * stack = state.stack;

		if (stack->is<LUA_TSTRING>(1)){
			AudioSpec * interfaceAS = state.getInterface<AudioSpec>("LuaSDL_AudioSpec");
			SDL_AudioSpec * inputSpec = interfaceAS->get(2);
			if (inputSpec){

				const std::string filename = stack->toLString(1);
				SDL_RWops * src = SDL_RWFromFile(filename.c_str(), "rb");
				if (!src){
					state.error("Couldn't open audio file: %s\n", filename.c_str());
				}
				Uint32 magic;
				SDL_AudioSpec wavespec, *audiospec = nullptr;
				Uint8 *abuf = nullptr;
				Uint32 alen;

				/* note: send a copy of the mixer spec */
				wavespec = *inputSpec;

				/* Find out what kind of audio file this is */
				magic = SDL_ReadLE32(src);
				/* Seek backwards for compatibility with older loaders */
				SDL_RWseek(src, -(int)sizeof(Uint32), RW_SEEK_CUR);

				switch (magic) {
				case WAVE:
				case RIFF:
					audiospec = SDL_LoadWAV_RW(src, 0, &wavespec,
						(Uint8 **)&abuf, &alen);
					break;
				case FORM:
					audiospec = Mix_LoadAIFF_RW(src, 0, &wavespec,
						(Uint8 **)&abuf, &alen);
					break;
				case OGGS:
					audiospec = Mix_LoadOGG_RW(src, 0, &wavespec,
						(Uint8 **)&abuf, &alen);
					break;
				case FLAC:
					audiospec = Mix_LoadFLAC_RW(src, 0, &wavespec,
						(Uint8 **)&abuf, &alen);
					break;
				case CREA:
					audiospec = Mix_LoadVOC_RW(src, 0, &wavespec,
						(Uint8 **)&abuf, &alen);
					break;
				default:
					if (detect_mp3((Uint8*)&magic))	{
						audiospec = Mix_LoadMP3_RW(src, 0, &wavespec,
							(Uint8 **)&abuf, &alen);
						break;
					}
					break;
				}
				SDL_RWclose(src);

				if (audiospec) {
					stack->pushLString(std::string(reinterpret_cast<char*>(abuf), alen));
					interfaceAS->push(audiospec, true);
					return 2;
				}
				else{
					state.error("Unreckonized audio file\n");
				}
			}
		}
		return 0;
	}
Beispiel #10
0
SDL_AudioSpec *Mix_LoadWAV_RW_(SDL_RWops *src, int freesrc,
                               SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
{
    /*
     * only process in case of 32000hz / 48000Hz (not 44100 / 22050 / 11025Hz)
     * part of codes were refered from bmx2wav/bmx2ogg project.
     */

    //
    // these part is already checked before, so don't do error checking
    //

    // RIFF header
    int riffheader = sdl_read_int(src);
#if 0
    if (riffheader != RIFF_HEADER)
    {
        ERROR
    }
#endif

    // file size
    sdl_read_int(src);

    // WAVE header
    int wavheader = sdl_read_int(src);
#if 0
    if (wavheader != WAVE_HEADER)
    {
        ERROR
    }
#endif

    // skip until met fmt chunk
    for (;;) {
        if (sdl_read_int(src) == FMT_CHUNK) {
            break;
        }
        sdl_read_skip(src, sdl_read_int(src));
    }

    // fmt byte size
    int fmt_byte_size = sdl_read_int(src);

    // fmt id
    if (sdl_read_short(src) != FMT_ID)
    {
        ERROR
    }

    // channel count
    int channel_count = sdl_read_short(src);
    if (channel_count != 1 && channel_count != 2)
    {
        ERROR
    }

    // frequency
    int frequency = sdl_read_int(src);

    // byte per second
    int byte_per_second = sdl_read_int(src);

    // block size
    int block_size = sdl_read_short(src);

    // bit rate
    int bit_rate = sdl_read_short(src);
    if (bit_rate != 4 &&
            bit_rate != 8 &&
            bit_rate != 16 &&
            bit_rate != 24 &&
            bit_rate != 32)
    {
        ERROR
    }

    // check once again (valid block size?)
    // as it's too minor problem, we'll gonna skip this
#if STRICT_CHECK
    if (block_size != (bit_rate / 8) * channel_count)
    {
        ERROR
    }
    if (byte_per_second != frequency * block_size)
    {
        ERROR
    }
#endif

    //
    // if bit is general one (8 / 16 / 32)
    // then use default SDL loader
    // otherwise (24 bit), load it by using this module.
    //
    if (bit_rate == 8 || bit_rate == 16 || bit_rate == 32) {
        SDL_RWseek(src, 0, RW_SEEK_SET);
        return SDL_LoadWAV_RW(src, freesrc, spec, audio_buf, audio_len);
    }

    // skip extended format byte
    if (fmt_byte_size - FMT_BYTE_SIZE > 0) {
        sdl_read_skip(src, fmt_byte_size - FMT_BYTE_SIZE);
    }

    // skip until met data chunk
    for (;;) {
        if (sdl_read_int(src) == DATA_CHUNK) {
            break;
        }
        sdl_read_skip(src, sdl_read_int(src));
    }

    // data size
    int data_size = sdl_read_int(src);

    // data size check
    if (data_size % ((bit_rate / 8) * channel_count) != 0) {
#if STRICT_CHECK
        // some WAVE file doesn't returns valid size
        // better fix it rather then returning ERROR
        ERROR
#else
        data_size -= data_size % ((bit_rate / 8) * channel_count);
#endif
    }

    //
    // get data size strictly by checking file size
    //
    Sint64 filetotsize = SDL_RWsize(src);
    Sint64 filepos = SDL_RWtell(src);
    if (filetotsize - filepos < data_size) data_size = filetotsize - filepos;

    //
    // now we know data size, so allocate buffer
    //
    *audio_buf = NULL;
    *audio_len = 0;
    memset(spec, '\0', sizeof(SDL_AudioSpec));

    //
    // convert it to 16bit, always,
    //
    spec->format = AUDIO_S16;
    spec->channels = channel_count;
    spec->freq = frequency;
    spec->samples = 4096; /* buffer size */

    int samples = data_size / (bit_rate / 8) / channel_count;

    /* x2 : we'll going to interpret audio data as 16bit */
    *audio_len = spec->size = samples * spec->channels * 2;
    *audio_buf = (Uint8 *)SDL_malloc(*audio_len);
    if (*audio_buf == NULL)
        goto done;

    //
    // all metadata were gathered... start to read WAV file
    // store raw if freq is 44100 / 22050 / 11025Hz.
    //
    int pos = 0;
    int mul = 2 * spec->channels;

    //
    // before continue, if wav file is 4 bit per sample,
    // then extend it into 16 bit per sample.
    //
#define READBIT read_bit_wav(src, bit_rate)
    if (bit_rate == 4) {
        // it's 2 sample per a byte, actually.
        bit_rate = 8;
        Uint16* write_buf = *audio_buf;
        for (int i = 0; i < samples / 2 * spec->channels; i++) {
            Uint16 _t = READBIT;
            *(write_buf++) = read_4bit_first(_t);
            *(write_buf++) = read_4bit_last(_t);
        }
    }
    else {
        for (int i = 0; i < samples; i++) {
            int bufpos = i * mul;
            *((Uint16*)(*audio_buf + bufpos)) = READBIT;
            if (spec->channels == 2)
                *((Uint16*)(*audio_buf + bufpos + 2)) = READBIT;
        }
    }

    /*
     * cleanup
     */
done:
    if (freesrc && src) {
        SDL_RWclose(src);
    }

    return(spec);
}
Beispiel #11
0
void read_dx_file() {
  int i,err;
  char buff[80];
  unzFile dat;
  UINT8 *buffer;
  unz_file_info file_info;
/*   int start,end; */
/*   short *src; */

  if (!dx_file[0])
    return;
  if (raine_nb_samples && emudx_samples && sample_data) {
    return;
  }

  dat = unzOpen(dx_file);
  if (!dat) return;
  for (raine_nb_samples=1; raine_nb_samples<32; raine_nb_samples++) {
    sprintf(buff,"%d.wav",raine_nb_samples);
    err = unzLocateFile(dat,buff,2);
    if (err != UNZ_OK)
      break;
  }
  raine_nb_samples--;

  emudx_samples = (struct wave_spec*)AllocateMem((raine_nb_samples+1) * sizeof(struct wave_spec));
  AddSaveData(ASCII_ID('S','A','M','P'),
	      (UINT8*)emudx_samples,
	      (raine_nb_samples+1) * sizeof(struct wave_spec));

  sample_data = (struct private_data*)AllocateMem((raine_nb_samples+1)*sizeof(struct private_data));
  for (i=1; i<=raine_nb_samples; i++) {
    sprintf(buff,"%d.wav",i);
    unzLocateFile(dat,buff,2);

    err = unzOpenCurrentFile(dat);
    unzGetCurrentFileInfo(dat,&file_info,NULL,0,NULL,0,NULL,0);
    buffer = malloc(file_info.uncompressed_size);
    unzReadCurrentFile(dat,buffer,file_info.uncompressed_size);
    emudx_samples[i].pos = emudx_samples[i].playing = 0;
#ifdef SDL
  SDL_RWops *rw;
  unsigned int len_in_bytes;
  SDL_AudioCVT  wav_cvt;
  SDL_AudioSpec wave;
  UINT8 *wav_buffer;
    extern SDL_AudioSpec gotspec;
    if (!gotspec.freq) {
	/* Now read_dx_file is called before the soundcard init, so we
	 * must put sensible default values here... */
	gotspec.freq = audio_sample_rate;
	gotspec.channels = 2;
	gotspec.format = AUDIO_S16;
    }
    rw = SDL_RWFromMem(buffer, file_info.uncompressed_size);
    if (!SDL_LoadWAV_RW(rw,1,&wave,&wav_buffer,&len_in_bytes)) {
      printf("couldn't load sample %d: %s\n",i,SDL_GetError());
      exit(1);
    }
    unzCloseCurrentFile(dat);	// Is this needed when open failed?

    if (SDL_BuildAudioCVT(&wav_cvt,
			  wave.format, wave.channels, wave.freq,
			  gotspec.format, gotspec.channels,gotspec.freq) == -1) {
      printf("can't build converter\n");
      exit(1);
    }

    wav_cvt.buf = sample_data[i].data = AllocateMem(len_in_bytes*wav_cvt.len_mult);
    sample_data[i].len =len_in_bytes*wav_cvt.len_ratio;
    wav_cvt.len = len_in_bytes;
    memcpy(sample_data[i].data, wav_buffer, len_in_bytes);
    SDL_FreeWAV(wav_buffer);

    SDL_ConvertAudio(&wav_cvt);
#else
    convert_wav((char*)buffer,file_info.uncompressed_size,
	    (char**)&sample_data[i].data,&sample_data[i].len);
#endif
    free(buffer);
  }
  unzClose(dat);
}
Beispiel #12
0
bool LoadSound(const char* filename, bool sfxr)
{
    auto it = sound_files.find(filename);
    Sound snd;

    if (it == sound_files.end())
    {
        size_t len = 0;
        uchar *buf = LoadFile(filename, &len);
        if (!buf)
            return false;

        if (sfxr)
        {
            snd.buf = buf;
            snd.len = len;
        }
        else
        {
            SDL_AudioSpec wav_spec;
            Uint32 wav_len;
            auto wav_spec_ret = SDL_LoadWAV_RW(SDL_RWFromMem(buf, (int)len), true, &wav_spec, &snd.buf, &wav_len);

            free(buf);

            if (!wav_spec_ret)
                return false;

            snd.len = wav_len;

            SDL_AudioCVT  wav_cvt;
            int ret = SDL_BuildAudioCVT(&wav_cvt,
                        wav_spec.format, wav_spec.channels, wav_spec.freq,
                        playbackspec.format, playbackspec.channels, playbackspec.freq);

            if (ret < 0)
            {
                SDL_FreeWAV(snd.buf);
                return false;
            }

            if (ret)
            {
                wav_cvt.buf = (uchar *)malloc(snd.len * wav_cvt.len_mult);
                wav_cvt.len = (int)snd.len;
                memcpy(wav_cvt.buf, snd.buf, snd.len);

                SDL_FreeWAV(snd.buf);

                SDL_ConvertAudio(&wav_cvt);

                snd.buf = wav_cvt.buf;
                // caution: len is not size of buffer anymore, but size of valid data..
                // that works ok with SDL_FreeWAV/free
                snd.len = size_t(wav_cvt.len * wav_cvt.len_ratio);
            }
        }

        snd.sfxr = sfxr;

        sound_files[filename] = snd;
    }
    else
    {
        snd = it->second;

        if (sfxr != snd.sfxr)   // wav file and sfxr file with same name? should be very rare :)
            return false;
    }

    if (sfxr)
    {
        uchar *file = snd.buf;

        int version = 0;
        fread_mem(&version, 1, sizeof(int), file);
        if(version!=102)
            return false;

        fread_mem(&wave_type, 1, sizeof(int), file);

        fread_mem(&sound_vol, 1, sizeof(float), file);

        fread_mem(&p_base_freq, 1, sizeof(float), file);
        fread_mem(&p_freq_limit, 1, sizeof(float), file);
        fread_mem(&p_freq_ramp, 1, sizeof(float), file);
        fread_mem(&p_freq_dramp, 1, sizeof(float), file);
        fread_mem(&p_duty, 1, sizeof(float), file);
        fread_mem(&p_duty_ramp, 1, sizeof(float), file);

        fread_mem(&p_vib_strength, 1, sizeof(float), file);
        fread_mem(&p_vib_speed, 1, sizeof(float), file);
        fread_mem(&p_vib_delay, 1, sizeof(float), file);

        fread_mem(&p_env_attack, 1, sizeof(float), file);
        fread_mem(&p_env_sustain, 1, sizeof(float), file);
        fread_mem(&p_env_decay, 1, sizeof(float), file);
        fread_mem(&p_env_punch, 1, sizeof(float), file);

        fread_mem(&filter_on, 1, sizeof(bool), file);
        fread_mem(&p_lpf_resonance, 1, sizeof(float), file);
        fread_mem(&p_lpf_freq, 1, sizeof(float), file);
        fread_mem(&p_lpf_ramp, 1, sizeof(float), file);
        fread_mem(&p_hpf_freq, 1, sizeof(float), file);
        fread_mem(&p_hpf_ramp, 1, sizeof(float), file);

        fread_mem(&p_pha_offset, 1, sizeof(float), file);
        fread_mem(&p_pha_ramp, 1, sizeof(float), file);
        fread_mem(&p_repeat_speed, 1, sizeof(float), file);
        fread_mem(&p_arp_speed, 1, sizeof(float), file);
        fread_mem(&p_arp_mod, 1, sizeof(float), file);
    }

    cursnd = snd;

    return true;
}