Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************/
- /******************************************************************************/
- //"ksdl2\src\main.cpp":
- #include <kit/all.hpp>
- using namespace kit;
- #define SDL_MAIN_HANDLED
- #include <SDL2/SDL.h>
- #include "../lodepng/lodepng.h"
- #include "./kit_sdl2/_kit_common.hpp"
- Mutex mutex;
- s32 threadfunc(void* userdata){
- userdata = userdata;
- for(int i=0; i<30; ++i){
- mutex.lock();
- SDL_Log(" before thread wait %i",i);
- //SDL_Delay(200);
- SDL_Delay(100);
- SDL_Log(" after thread wait %i",i);
- mutex.unlock();
- SDL_Delay((rand()>16384) ? 4 : 1);
- }
- SDL_Log("exiting thread...");
- return 0;
- }
- #define _PI 3.1415926535897932384626433
- #define _2PI (_PI+_PI)
- bool audiocallback(void* _stream, const AudioDeviceInfo* info){
- static u64 smp = 0;
- f32* stream = (f32*)_stream;
- u32 stream_len = info->sampleFrames;
- u32 sampleRate = info->sampleRate;
- for(u32 i=0; i<stream_len; ++i, ++smp){
- f64 value = ((f64)smp/sampleRate) * _2PI * 440;
- stream[i] = (f32)SDL_sin(value)*0.1f;
- }
- return smp < sampleRate*2;
- }
- int main(/*int argc, char** argv*/){ try { {
- initSubsystems(KINIT_EVENTS|KINIT_AUDIO);
- srand(SDL_GetTicks());
- /*
- Window win(nullptr, 640, 480, WINFLAG_RESIZABLE);
- win.setMouseGrab(true);
- bool fullscreen = false;
- bool run = true;
- while(run){
- Event evt;
- while(run && pollEvent(&evt))
- switch(evt.type){
- case KEVENT_QUIT: run = false; break;
- case KEVENT_KEY_DOWN: {
- switch(evt.key.vkey){
- case VKEY_F11: win.setFullscreen(1*(fullscreen^=1)); break;
- default:;
- }
- } break;
- default:;
- }
- }
- */
- {
- AudioDeviceInfo info;
- info.sampleRate = 8000;
- info.sampleFrames = 512;
- info.sampleFormat = SMPFMT_F32;
- info.numChannels = 1;
- info.zeroBuffer = true;
- info.callback = audiocallback;
- AudioDevice adev(-1, &info, false);
- SDL_Log("waiting to start...");
- u32 timeStart = time::getMS_32();
- adev.playAndWait();
- SDL_Log("time taken to start: %u", time::getMS_32()-timeStart);
- timeStart = time::getMS_32();
- while(adev.isPlaying()) time::sleep(50);
- SDL_Log("time taken rendering audio: %u", time::getMS_32()-timeStart);
- timeStart = time::getMS_32();
- adev.pauseAndWait();
- SDL_Log("time taken to fade out: %u", time::getMS_32()-timeStart);
- }
- }
- quitSubsystems(KINIT_EVERYTHING);
- return 0;
- } catch(const char* errorText){
- #ifdef _DEBUG
- SDL_Log("FATAL EXCEPTION OCCURRED: \"%s\"\n", errorText);
- #else
- showMsgBox(fstr("Error: %-14s", errorText),
- "FATAL EXCEPTION OCCURRED!", MSGBOX_ERROR);
- #endif /* _DEBUG */
- //redundant, since quitSubsystems(KINIT_EVERYTHING)
- //frees all thread errors automatically anyway
- //freeThreadError();
- _getnumallocs
- quitSubsystems(KINIT_EVERYTHING);
- _getnumallocs
- return -1;
- }}
- /******************************************************************************/
- /******************************************************************************/
- //"ksdl2\src\kit_sdl2\kit_AudioCallbackWrapper.cpp":
- #include "_kit_common.hpp"
- namespace kit {
- //workaround for having _AudioCallbackWrapper pause the device,
- //without having to call SDL_PauseAudioDevice inside the callback itself
- static int _AudioPauseThread(void* data){
- _AudioDeviceOpaque* opq = (_AudioDeviceOpaque*)data;
- SDL_AudioDeviceID devID = opq->info_p->deviceID;
- //wait for the callback to exit before actually pausing
- SDL_LockAudioDevice(devID);
- SDL_PauseAudioDevice(devID, 1);
- SDL_UnlockAudioDevice(devID);
- return 0;
- }
- static inline bool startPauseThread(_AudioDeviceOpaque* opq){
- SDL_Thread* pauseThread = SDL_CreateThread(_AudioPauseThread, "kADPause", opq);
- if(pauseThread) SDL_DetachThread(pauseThread);
- else opq->fadeDelay = KIT_U32_MAX;
- opq->fadeOut = false;
- opq->playing = false;
- return pauseThread != nullptr;
- }
- //not inlined
- static void apply_fade(_AudioDeviceOpaque* opq,
- f32* stream, u32 stream_len)
- {
- f32 fadeDelta = opq->fadeDelta;
- f32 fadeVolume = opq->fadeVolume;
- u32 fadeDelay = opq->fadeDelay;
- u8 numChannels = opq->info_p->numChannels;
- u32 smp = 0; //this index is shared, as the loops can jump to others at will
- //FADING OUT
- if(opq->fadeOut){
- _FadeOut:;
- for(; smp<stream_len; ++smp){
- //if audio device starts fading in mid-fadeout, jump to the fade-in loop
- if(!opq->fadeOut) goto _FadeIn;
- stream[smp] *= fadeVolume;
- //only change fadeVolume every numChannels samples,
- //so that there's 1 fadeVolume state per sample frame
- if(!((smp+1)%numChannels)) fadeVolume -= fadeDelta;
- //to enforce a minimum volume
- if(fadeVolume < 0.0f) fadeVolume = 0.0f;
- }
- //trigger pause thread if fade out is complete
- if(fadeVolume == 0.0f)
- startPauseThread(opq);
- //FADING IN
- } else if(fadeVolume < 1.0f){
- //let stream warm up before fading in (if fadeDelay != 0)
- for(; (fadeDelay)&&(smp<stream_len); ++smp){
- stream[smp] = 0.0f;
- if(!((smp+1)%numChannels)) --fadeDelay;
- }
- _FadeIn:;
- for(; smp<stream_len; ++smp){
- if(opq->fadeOut) goto _FadeOut;
- stream[smp] *= fadeVolume;
- if(!((smp+1)%numChannels)) fadeVolume += fadeDelta;
- if(fadeVolume > 1.0f) fadeVolume = 1.0f;
- }
- }
- //update relevant in opq
- opq->fadeVolume = fadeVolume;
- opq->fadeDelay = fadeDelay;
- }
- //for multiplying the by inverse of stuff
- #define INV_S8 0.0078125000000000000000000000000f // = 1.0f/0x80
- #define INV_S16 0.0000305175781250000000000000000f // = 1.0f/0x8000
- #define INV_S32 0.0000000004656612873077392578125f // = 1.0f/0x80000000
- #define fmtconvloop for(u32 i=0; i<length; ++i) to
- //used for output devices
- //(length should be in samples, not sample frames)
- static inline void fmt_to_f32(Mono_smp from, f32* to,
- u32 length, u16 from_fmt)
- {
- switch(from_fmt){
- case SMPFMT_U8 : fmtconvloop[i] = ((f32)from.u8_ [i]-128 )*INV_S8 ; break;
- case SMPFMT_S8 : fmtconvloop[i] = ((f32)from.s8_ [i] )*INV_S8 ; break;
- case SMPFMT_U16: fmtconvloop[i] = ((f32)from.u16_[i]-32768)*INV_S16; break;
- case SMPFMT_S16: fmtconvloop[i] = ((f32)from.s16_[i] )*INV_S16; break;
- case SMPFMT_S32: fmtconvloop[i] = ((f32)from.s32_[i] )*INV_S32; break;
- case SMPFMT_F32: memory::copy(to, from.f32_, length*sizeof(f32)); break;
- //(f32 samples aren't hard-clipped! make sure to keep them -1.0f -> 1.0f)
- }
- }
- //used for input devices
- //(again, length should be in samples, not sample frames)
- static inline void f32_to_fmt(f32* from, Mono_smp to,
- u32 length, u16 to_fmt)
- {
- //(input f32 samples aren't hard-clipped here either!)
- switch(to_fmt){
- case SMPFMT_U8 : fmtconvloop.u8_ [i] = (u8 )(from[i]*127 + 128 ); break;
- case SMPFMT_S8 : fmtconvloop.s8_ [i] = (s8 )(from[i]*127 ); break;
- case SMPFMT_U16: fmtconvloop.u16_[i] = (u16)(from[i]*32767 + 32768); break;
- case SMPFMT_S16: fmtconvloop.s16_[i] = (s16)(from[i]*32767 ); break;
- case SMPFMT_S32: fmtconvloop.s32_[i] = (s32)(from[i]*0x7fffffff ); break;
- case SMPFMT_F32: memory::copy(to.f32_, from, length*sizeof(f32));
- }
- }
- void _AudioCallbackWrapper(void* userdata, u8* _stream, int len){
- u64 timeStartTicks = SDL_GetPerformanceCounter();
- u64 timeStartMS = SDL_GetTicks64();
- AudioDevice* device = (AudioDevice*)userdata;
- f32* stream = (f32*)_stream;
- u32 stream_size = len;
- u32 stream_len = len / sizeof(f32); //samples, not sample frames
- _AudioDeviceOpaque* opq = (_AudioDeviceOpaque*)KIT_GET_CLASS_OPAQUE(device);
- AudioDeviceInfo* info_p = opq->info_p;
- info_p->timeStartTicks = timeStartTicks;
- info_p->timeStartMS = timeStartMS;
- //if pause thread failed to start, simply write zeros to stream and exit
- if(opq->fadeDelay == KIT_U32_MAX){
- if(!info_p->isInput) memory::set(stream, 0, stream_size);
- return;
- }
- if(!info_p->isInput){ //buffer will be written to
- //(memset 0 the _user_ buffer, not the sdl stream)
- if(info_p->zeroBuffer) memory::set(opq->buffer, 0, opq->buffer_size);
- try { //attempt to call user callback
- if(info_p->callback)
- opq->fadeOut = !info_p->callback(opq->buffer, info_p);
- } catch(const char* errortext){
- SDL_Log("ERROR IN AUDIO CALLBACK: \"%s\"", errortext);
- freeThreadError();
- //set back to 0, since used callback failed
- memory::set(stream, 0, stream_size);
- }
- //copy buffer to stream (X to f32)
- fmt_to_f32(opq->buffer, stream, stream_len, info_p->sampleFormat);
- //apply fade to stream
- apply_fade(opq, stream, stream_len);
- } else { //buffer will be read from
- //apply fade to stream
- apply_fade(opq, stream, stream_len);
- //copy stream to buffer (f32 to X)
- f32_to_fmt(stream, opq->buffer, stream_len, info_p->sampleFormat);
- try { //attempt to call user callback
- if(info_p->callback)
- opq->fadeOut = !info_p->callback(opq->buffer, info_p);
- } catch(const char* errortext){
- SDL_Log("ERROR IN AUDIO CALLBACK: \"%s\"", errortext);
- freeThreadError();
- }
- }
- }
- }; /* namespace kit */
- /******************************************************************************/
- /******************************************************************************/
- //"ksdl2\src\kit_sdl2\kit_AudioDevice.cpp":
- #include "_kit_common.hpp"
- #define INDEX_FUNC "AudioDevice::AudioDevice(index)"
- #define NAME_FUNC "AudioDevice::AudioDevice(name)"
- #define DEVICE_IS_INVALID (!_valid && !_constructing)
- #define CONSTRUCTOR_ERR(_txt) PUSH_ERRORF("%s: " _txt , funcname)
- #define CONSTRUCTOR_ERRSDL PUSH_ERRORF("%s: \"%s\"", funcname, SDL_GetError())
- #define DEV_PTR ((_AudioDeviceOpaque*)_opq)
- namespace kit {
- //in "kit_AudioCallbackWrapper.cpp"
- void _AudioCallbackWrapper(void* userdata, u8* _stream, int len);
- static inline u32 _count_bits(u32 num){
- u32 count = 0;
- while(num > 0){
- if(num&1) ++count;
- num >>= 1;
- }
- return count;
- }
- //not inlined
- static void validate_smpfmt(u16 sampleFormat, const char* funcname){
- switch(sampleFormat){
- case SMPFMT_U8 :
- case SMPFMT_S8 :
- case SMPFMT_U16LSB:
- case SMPFMT_S16LSB:
- //case SMPFMT_U16MSB:
- //case SMPFMT_S16MSB:
- case SMPFMT_S32LSB:
- //case SMPFMT_S32MSB:
- case SMPFMT_F32LSB:
- //case SMPFMT_F32MSB:
- case 0 : break;
- default: throw PUSH_ERRORF("%s: unknown sample format 0x%04X",
- funcname, sampleFormat);
- }
- }
- static inline void validate_desired(const AudioDeviceInfo* desired,
- const char* funcname)
- {
- if(desired->sampleRate > KIT_S32_MAX)
- throw PUSH_ERRORF("%s: desired->sampleRate > KIT_S32_MAX", funcname);
- if(_count_bits(desired->sampleFrames) > 1)
- throw PUSH_ERRORF("%s: desired->sampleFrames is not a power of 2", funcname);
- validate_smpfmt(desired->sampleFormat, funcname);
- if(desired->numChannels > 8)
- throw PUSH_ERRORF("%s: desired->numChannels > 8", funcname);
- if(desired->callback == nullptr)
- throw PUSH_ERRORF("%s: desired->callback = nullptr", funcname);
- }
- static inline s32 get_dev_params(SDL_AudioSpec& want,
- const AudioDeviceInfo* desired,
- AudioDevice* device)
- {
- want.freq = (s32)((desired->sampleRate) ? desired->sampleRate : 48000);
- want.format = AUDIO_F32LSB;
- want.channels = (desired->numChannels) ? desired->numChannels : 2;
- want.samples = (desired->sampleFrames) ? desired->sampleFrames : 4096;
- want.callback = _AudioCallbackWrapper;
- want.userdata = device;
- s32 allowed_changes = 0;
- if(!desired->sampleRate ) allowed_changes |= SDL_AUDIO_ALLOW_FREQUENCY_CHANGE;
- if(!desired->sampleFormat) allowed_changes |= SDL_AUDIO_ALLOW_FORMAT_CHANGE;
- if(!desired->numChannels ) allowed_changes |= SDL_AUDIO_ALLOW_CHANNELS_CHANGE;
- if(!desired->sampleFrames) allowed_changes |= SDL_AUDIO_ALLOW_SAMPLES_CHANGE;
- return allowed_changes;
- }
- static inline AudioDeviceInfo set_dev_info(SDL_AudioDeviceID deviceID,
- SDL_AudioSpec have,
- const AudioDeviceInfo* desired)
- {
- AudioDeviceInfo info;
- //info.timeStartTicks = 0;
- //info.timeStartMS = 0;
- info.deviceID = deviceID;
- info.sampleRate = have.freq;
- info.sampleFrames = have.samples;
- info.sampleFormat = have.format;
- info.sampleFrameSize = KIT_AUDIO_BYTESIZE(have.format)*have.channels;
- info.numChannels = have.channels;
- info.isInput = desired->isInput;
- info.zeroBuffer = desired->zeroBuffer;
- info.callback = desired->callback;
- info.userdata = desired->userdata;
- return info;
- }
- AudioDevice::AudioDevice(s32 index, //-1 to use default device
- const AudioDeviceInfo* desired,
- bool disableFadeDelay)
- {
- //check if desired is nullptr, since ->isInput is necessary to get device name
- if(desired == nullptr) throw PUSH_ERROR(INDEX_FUNC ": desired = nullptr");
- const char* name = nullptr;
- if(index >= 0){
- name = SDL_GetAudioDeviceName(index, desired->isInput);
- if(name == nullptr)
- throw PUSH_ERRORF(INDEX_FUNC ": \"%s\"", SDL_GetError());
- }
- _construct(name, desired, disableFadeDelay);
- }
- void AudioDevice::_construct(const char* name,
- const AudioDeviceInfo* desired,
- bool disableFadeDelay,
- bool indexed)
- {
- _type = KIT_CLASSTYPE_AUDIODEVICE;
- const char* funcname = (indexed) ? INDEX_FUNC : NAME_FUNC;
- if(desired == nullptr) throw PUSH_ERRORF("%s: desired = nullptr", funcname);
- AudioDeviceInfo* info_p = (AudioDeviceInfo*)&info; //info is normally const
- //a few domain checks
- validate_desired(desired, funcname);
- SDL_AudioSpec want, have;
- s32 allowed_changes = get_dev_params(want, desired, this);
- //actually create the device
- SDL_AudioDeviceID deviceID = SDL_OpenAudioDevice(name, desired->isInput,
- &want, &have, allowed_changes);
- if(!deviceID) throw PUSH_ERRORF("%s: \"%s\"", funcname, SDL_GetError());
- if(desired->sampleFormat) have.format = desired->sampleFormat;
- else validate_smpfmt(have.format, funcname);
- *info_p = set_dev_info(deviceID, have, desired);
- _opq = memory::alloc(sizeof(_AudioDeviceOpaque));
- if(_opq == nullptr){
- SDL_CloseAudioDevice(info.deviceID);
- throw PUSH_ERRORF("%s: failed to allocate memory for opaque struct", funcname);
- }
- memory::set(_opq, 0, sizeof(_AudioDeviceOpaque));
- DEV_PTR->info_p = info_p;
- DEV_PTR->buffer_size = info.sampleFrames * info.sampleFrameSize;
- DEV_PTR->buffer = memory::alloc(DEV_PTR->buffer_size);
- DEV_PTR->fadeDelta = 1.0f / ((f32)info.sampleRate*FADEDELTA_SEC);
- //DEV_PTR->fadeVolume = 0.0f;
- //DEV_PTR->fadeDelay = 0;
- //DEV_PTR->fadeOut = false;
- DEV_PTR->noFadeDelay = disableFadeDelay;
- //DEV_PTR->playing = false;
- if(DEV_PTR->buffer == nullptr){
- memory::free(&_opq);
- SDL_CloseAudioDevice(info.deviceID);
- throw PUSH_ERRORF("%s: failed to allocate memory for audio buffer", funcname);
- }
- memory::set(DEV_PTR->buffer, 0, DEV_PTR->buffer_size);
- _valid = true;
- _constructing = false;
- }
- AudioDevice::~AudioDevice(){
- if(!_valid) return;
- _valid = false;
- if(info.deviceID != 0) SDL_CloseAudioDevice(info.deviceID);
- if(_opq != nullptr){
- memory::free(&DEV_PTR->buffer);
- memory::free(&_opq);
- }
- }
- bool AudioDevice::isPlaying(){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::isPlaying(): invalid device");
- //return SDL_GetAudioDeviceStatus(info.deviceID) == SDL_AUDIO_PLAYING;
- return DEV_PTR->playing;
- }
- bool AudioDevice::isActive(){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::isActive(): invalid device");
- return SDL_GetAudioDeviceStatus(info.deviceID) == SDL_AUDIO_PLAYING;
- //return DEV_PTR->playing;
- }
- void AudioDevice::setCallback(AudioCallback callback){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::setCallback(): invalid device");
- if(callback == nullptr)
- throw PUSH_ERROR("AudioDevice::setCallback(): callback = nullptr");
- SDL_LockAudioDevice(info.deviceID);
- ((AudioDeviceInfo*)&info)->callback = callback;
- SDL_UnlockAudioDevice(info.deviceID);
- }
- void AudioDevice::setUserdata(void* userdata){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::setUserdata(): invalid device");
- SDL_LockAudioDevice(info.deviceID);
- ((AudioDeviceInfo*)&info)->userdata = userdata;
- SDL_UnlockAudioDevice(info.deviceID);
- }
- void AudioDevice::setPlayback(bool playing){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::setPlayback(): invalid device");
- //this should occur when _AudioCallbackWrapper
- //fails to trigger the pause thread
- if(DEV_PTR->fadeDelay == KIT_U32_MAX){
- SDL_LockAudioDevice(info.deviceID);
- SDL_PauseAudioDevice(info.deviceID, true);
- DEV_PTR->fadeVolume = 0.0f;
- DEV_PTR->fadeDelay = 0;
- DEV_PTR->fadeOut = false;
- DEV_PTR->playing = false;
- SDL_UnlockAudioDevice(info.deviceID);
- }
- DEV_PTR->fadeOut = !playing;
- if(playing && !DEV_PTR->playing){
- //the purpose of fadeDelay is to mute for some samples
- //to give the sdl audio device some time to warm up,
- //otherwise artifacts start to occur (for me, anyway)
- if(!DEV_PTR->noFadeDelay) DEV_PTR->fadeDelay = (u32)(info.sampleRate * FADEDELAY_SEC);
- else DEV_PTR->fadeDelay = 0;
- DEV_PTR->fadeVolume = 0.0f;
- DEV_PTR->playing = true;
- SDL_PauseAudioDevice(info.deviceID, false);
- }
- }
- void AudioDevice::setPlaybackAndWait(bool playing){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::setPlaybackAndWait(): invalid device");
- bool wasPlaying = DEV_PTR->playing;
- setPlayback(playing);
- if(playing && !wasPlaying && !DEV_PTR->noFadeDelay){
- time::sleep((u32)( FADETOTAL_SEC*1000 ));
- } else {
- time::sleep((u32)( FADEDELTA_SEC*1000 ));
- }
- }
- void AudioDevice::lock(bool locked){
- if(DEVICE_IS_INVALID)
- throw PUSH_ERROR("AudioDevice::lock(): invalid device");
- if(locked) SDL_LockAudioDevice(info.deviceID);
- else SDL_UnlockAudioDevice(info.deviceID);
- }
- }; /* namespace kit */
- /******************************************************************************/
- /******************************************************************************/
- //"ksdl2\src\kit_sdl2\kit_audio_func.cpp":
- #include "_kit_common.hpp"
- #define AUDIO_UNINIT_CHECK(_funcname) \
- if(!_gl.init.audio){ throw PUSH_ERROR(_funcname ": audio subsystem is uninitialized"); }
- namespace kit {
- static AudioDeviceInfo _AudioSpecToDevInfo(SDL_AudioSpec& spec, bool isInput){
- AudioDeviceInfo info;
- info.sampleRate = spec.freq; //(hopefully freq is never negative!)
- info.sampleFrames = spec.samples;
- info.sampleFormat = spec.format;
- info.sampleFrameSize = KIT_AUDIO_BYTESIZE(spec.format)*spec.channels;
- info.numChannels = spec.channels;
- info.isInput = isInput;
- return info;
- }
- AudioDeviceInfo audio::getDefaultDevInfo(char** name_p, bool isInput){
- AUDIO_UNINIT_CHECK("audio::getDefaultDevInfo()");
- SDL_AudioSpec spec;
- if(SDL_GetDefaultAudioInfo(name_p, &spec, isInput) != 0)
- throw PUSH_ERRORF("audio::getDefaultDevInfo(): \"%s\"", SDL_GetError());
- if(name_p != nullptr)
- ++numAllocations; //memory has been allocated; increment # of allocations
- return _AudioSpecToDevInfo(spec, isInput);
- }
- AudioDeviceInfo audio::getDeviceInfo(s32 index, bool isInput){
- AUDIO_UNINIT_CHECK("audio::getDeviceInfo()");
- SDL_AudioSpec spec;
- if(SDL_GetAudioDeviceSpec(index, isInput, &spec) != 0)
- throw PUSH_ERRORF("audio::getDeviceInfo(): \"%s\"", SDL_GetError());
- return _AudioSpecToDevInfo(spec, isInput);
- }
- s32 audio::getNumDevices(bool isInput){
- AUDIO_UNINIT_CHECK("audio::getNumDevices()");
- return SDL_GetNumAudioDevices(isInput);
- }
- const char* audio::getDeviceName(u32 index, bool isInput){
- AUDIO_UNINIT_CHECK("audio::getDeviceName()");
- if(index > KIT_S32_MAX)
- throw PUSH_ERROR("audio::getDeviceName(): index > KIT_S32_MAX");
- const char* name = SDL_GetAudioDeviceName((s32)index, isInput);
- if(name == nullptr)
- throw PUSH_ERRORF("audio::getDeviceName(): \"%s\"", SDL_GetError());
- return name;
- }
- }; /* namespace kit */
- /******************************************************************************/
- /******************************************************************************/
- //"ksdl2\src\kit_sdl2\kit_fileio.cpp":
- #include "_kit_common.hpp"
- //a wrapper; fileio::remove and remove are treated as the same inside fileio
- static inline int _remove(const char* filePath){ return remove(filePath); }
- namespace kit {
- BinaryData::BinaryData(const char* filePath){
- _type = KIT_CLASSTYPE_BINARYDATA;
- _data = (char*)SDL_LoadFile(filePath, &_data_len);
- if(_data == nullptr)
- throw PUSH_ERRORF("BinaryData::BinaryData(file): \"%s\"", SDL_GetError());
- ++numAllocations;
- _valid = true;
- _constructing = false;
- }
- BinaryData::BinaryData(const void* data, size_t data_len){
- _type = KIT_CLASSTYPE_BINARYDATA;
- if(data_len == KIT_U64_MAX)
- throw PUSH_ERROR("BinaryData::BinaryData(memory): data_len = KIT_U64_MAX"); //lol
- _data = (char*)memory::alloc(data_len+1);
- if(_data == nullptr)
- throw PUSH_ERROR("BinaryData::BinaryData(memory): failed to allocate memory for _data");
- _data_len = data_len;
- _data[data_len] = 0; //add null-terminator for convenience
- if(data != nullptr) memory::copy(_data, data, data_len);
- _valid = true;
- _constructing = false;
- }
- BinaryData::~BinaryData(){
- if(!_valid) return;
- _valid = false;
- if(_data != nullptr) memory::free(&_data);
- }
- //unlike the other fileio functions and whatnot,
- //this obviously doesn't throw if the file doesn't exist
- bool fileio::exists(const char* filePath){
- if(filePath == nullptr)
- throw PUSH_ERROR("fileio::exists(): filePath = nullptr");
- SDL_RWops* file = SDL_RWFromFile(filePath, "rb");
- if(file != nullptr)
- SDL_RWclose(file);
- return file != nullptr;
- }
- size_t fileio::size(const char* filePath){
- if(filePath == nullptr)
- throw PUSH_ERROR("fileio::size(): filePath = nullptr");
- SDL_RWops* file = SDL_RWFromFile(filePath, "rb");
- if(file == nullptr)
- throw PUSH_ERRORF("fileio::size(): \"%s\"", SDL_GetError());
- if(SDL_RWseek(file, 0, RW_SEEK_END)<0){
- SDL_RWclose(file);
- throw PUSH_ERRORF("fileio::size(): \"%s\"", SDL_GetError());
- }
- s64 fileSize = SDL_RWtell(file);
- if(fileSize < 0){
- //since SDL_RWclose() can overwrite the previous result of SDL_GetError(),
- //the result of fstr is cached before SDL_RWclose() is actually called
- const char* fstr_result = fstr("fileio::size(): \"%s\"", SDL_GetError());
- SDL_RWclose(file);
- throw PUSH_ERROR(fstr_result);
- }
- SDL_RWclose(file);
- return (size_t)fileSize;
- }
- void fileio::remove(const char* filePath){
- if(filePath == nullptr)
- throw PUSH_ERROR("fileio::remove(): filePath = nullptr");
- if(_remove(filePath) != 0) //this is a wrapper for remove() (see line 5)
- throw PUSH_ERRORF("fileio::remove(): failed to delete file \"%s\"", filePath);
- }
- //heap memory is allocated here,
- //and should be freed with memory::free()
- //(also, while *dataSize_p won't be populated with resulting
- // filesize if dataSize_p is nullptr, it won't actually error)
- void* fileio::readAll(const char* filePath, size_t* dataSize_p){
- if(filePath == nullptr)
- throw PUSH_ERROR("fileio::readAll(): filePath = nullptr");
- void* data = SDL_LoadFile(filePath, dataSize_p);
- if(data == nullptr)
- throw PUSH_ERRORF("fileio::readAll(): \"%s\"", SDL_GetError());
- ++numAllocations;
- return data;
- }
- //writes to a binary file from a buffer
- void fileio::writeAll(const char* filePath, const void* data,
- size_t dataSize, bool append)
- {
- if(filePath == nullptr) throw PUSH_ERROR("fileio::writeAll(): filePath = nullptr");
- if(data == nullptr) throw PUSH_ERROR("fileio::writeAll(): data = nullptr");
- SDL_RWops* file = SDL_RWFromFile(filePath, (append) ? "ab" : "wb");
- if(file == nullptr)
- throw PUSH_ERRORF("fileio::writeAll(): \"%s\"", SDL_GetError());
- size_t bytesWritten = SDL_RWwrite(file, data, 1, dataSize);
- SDL_RWclose(file);
- if(bytesWritten < dataSize)
- throw PUSH_ERROR("fileio::writeAll(): bytesWritten < dataSize");
- }
- }; /* namespace kit */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement