You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
2.5 KiB
125 lines
2.5 KiB
#include "all.h" |
|
#include "stubs.h" |
|
#include <SDL.h> |
|
|
|
#include "storm_sdl_rw.h" |
|
|
|
namespace dvl { |
|
|
|
///// SoundSample ///// |
|
|
|
void SoundSample::Release() |
|
{ |
|
Mix_FreeChunk(chunk); |
|
chunk = NULL; |
|
}; |
|
|
|
/** |
|
* @brief Check if a the sound is being played atm |
|
*/ |
|
bool SoundSample::IsPlaying() |
|
{ |
|
if (chunk == NULL) |
|
return false; |
|
|
|
int channels = Mix_AllocateChannels(-1); |
|
for (int i = 0; i < channels; i++) { |
|
if (Mix_GetChunk(i) == chunk && Mix_Playing(i)) { |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
}; |
|
|
|
/** |
|
* @brief Start playing the sound |
|
*/ |
|
void SoundSample::Play(int lVolume, int lPan, int channel) |
|
{ |
|
if (chunk == NULL) |
|
return; |
|
|
|
channel = Mix_PlayChannel(channel, chunk, 0); |
|
if (channel == -1) { |
|
SDL_Log("Too few channels, skipping sound"); |
|
return; |
|
} |
|
|
|
Mix_Volume(channel, pow((double)10, (double)lVolume / 2000.0) * MIX_MAX_VOLUME); |
|
int pan = copysign(pow((double)10, -abs(lPan) / 2000.0) * 255, (double)lPan); |
|
Mix_SetPanning(channel, pan > 0 ? pan : 255, pan < 0 ? abs(pan) : 255); |
|
}; |
|
|
|
/** |
|
* @brief Stop playing the sound |
|
*/ |
|
void SoundSample::Stop() |
|
{ |
|
if (chunk == NULL) |
|
return; |
|
|
|
int channels = Mix_AllocateChannels(-1); |
|
for (int i = 0; i < channels; i++) { |
|
if (Mix_GetChunk(i) != chunk) { |
|
continue; |
|
} |
|
|
|
Mix_HaltChannel(i); |
|
} |
|
}; |
|
|
|
int SoundSample::SetChunkStream(HANDLE stormHandle) |
|
{ |
|
chunk = Mix_LoadWAV_RW(SFileRw_FromStormHandle(stormHandle), /*freesrc=*/1); |
|
if (chunk == NULL) { |
|
SDL_Log("Mix_LoadWAV_RW: %s", Mix_GetError()); |
|
return -1; |
|
} |
|
return 0; |
|
} |
|
|
|
/** |
|
* @brief This can load WAVE, AIFF, RIFF, OGG, and VOC formats |
|
* @param fileData Buffer containing file data |
|
* @param dwBytes Length of buffer |
|
* @return 0 on success, -1 otherwise |
|
*/ |
|
int SoundSample::SetChunk(BYTE *fileData, DWORD dwBytes) |
|
{ |
|
SDL_RWops *buf1 = SDL_RWFromConstMem(fileData, dwBytes); |
|
if (buf1 == NULL) { |
|
return -1; |
|
} |
|
|
|
chunk = Mix_LoadWAV_RW(buf1, 1); |
|
if (chunk == NULL) { |
|
return -1; |
|
} |
|
|
|
return 0; |
|
}; |
|
|
|
/** |
|
* @return Audio duration in ms |
|
*/ |
|
int SoundSample::GetLength() |
|
{ |
|
if (chunk == NULL) |
|
return 0; |
|
|
|
int frequency, channels; |
|
Uint16 format; |
|
Mix_QuerySpec(&frequency, &format, &channels); |
|
|
|
int bytePerSample = 2; |
|
if (format == AUDIO_U8 || format == AUDIO_S8) { |
|
bytePerSample = 1; |
|
} |
|
|
|
Uint64 ms = 1000; // milliseconds, 64bit to avoid overflow when multiplied by alen |
|
Uint32 bps = frequency * channels * bytePerSample; // bytes per second |
|
return (Uint32)(chunk->alen * ms / bps); |
|
}; |
|
|
|
} // namespace dvl
|
|
|