/* 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 ) { 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: #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC) if (detect_mp3((Uint8*)&magic)) { /* note: send a copy of the mixer spec */ wavespec = mixer; loaded = Mix_LoadMP3_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; } #endif 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); } SDL_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); }
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; }