2022-06-28 07:00:08 +00:00
|
|
|
/**
|
|
|
|
* Furnace Tracker - multi-system chiptune tracker
|
|
|
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sfWrapper.h"
|
|
|
|
#include "../fileutils.h"
|
2022-06-29 03:08:24 +00:00
|
|
|
#include "sndfile.h"
|
2022-06-28 07:00:08 +00:00
|
|
|
|
|
|
|
sf_count_t _vioGetSize(void* user) {
|
|
|
|
return ((SFWrapper*)user)->ioGetSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t _vioSeek(sf_count_t offset, int whence, void* user) {
|
|
|
|
return ((SFWrapper*)user)->ioSeek(offset,whence);
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t _vioRead(void* ptr, sf_count_t count, void* user) {
|
|
|
|
return ((SFWrapper*)user)->ioRead(ptr,count);
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t _vioWrite(const void* ptr, sf_count_t count, void* user) {
|
|
|
|
return ((SFWrapper*)user)->ioWrite(ptr,count);
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t _vioTell(void* user) {
|
|
|
|
return ((SFWrapper*)user)->ioTell();
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t SFWrapper::ioGetSize() {
|
2022-06-29 03:08:24 +00:00
|
|
|
sf_count_t ret=(sf_count_t)len;
|
|
|
|
if (fileMode==SFM_WRITE || fileMode==SFM_RDWR) {
|
|
|
|
ssize_t lastTell=ftell(f);
|
|
|
|
fseek(f,0,SEEK_END);
|
|
|
|
ret=(sf_count_t)ftell(f);
|
|
|
|
fseek(f,lastTell,SEEK_SET);
|
|
|
|
}
|
|
|
|
return ret;
|
2022-06-28 07:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t SFWrapper::ioSeek(sf_count_t offset, int whence) {
|
|
|
|
return fseek(f,offset,whence);
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t SFWrapper::ioRead(void* ptr, sf_count_t count) {
|
|
|
|
return fread(ptr,1,count,f);
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t SFWrapper::ioWrite(const void* ptr, sf_count_t count) {
|
|
|
|
return fwrite(ptr,1,count,f);
|
|
|
|
}
|
|
|
|
|
|
|
|
sf_count_t SFWrapper::ioTell() {
|
|
|
|
return ftell(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
int SFWrapper::doClose() {
|
|
|
|
int ret=sf_close(sf);
|
|
|
|
fclose(f);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
SNDFILE* SFWrapper::doOpen(const char* path, int mode, SF_INFO* sfinfo) {
|
|
|
|
vio.get_filelen=_vioGetSize;
|
|
|
|
vio.read=_vioRead;
|
|
|
|
vio.seek=_vioSeek;
|
|
|
|
vio.tell=_vioTell;
|
|
|
|
vio.write=_vioWrite;
|
|
|
|
|
|
|
|
const char* modeC="rb";
|
|
|
|
if (mode==SFM_WRITE) {
|
|
|
|
modeC="wb";
|
|
|
|
}
|
|
|
|
if (mode==SFM_RDWR) {
|
|
|
|
modeC="rb+";
|
|
|
|
}
|
|
|
|
|
|
|
|
f=ps_fopen(path,modeC);
|
|
|
|
if (f==NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fseek(f,0,SEEK_END)==-1) {
|
|
|
|
fclose(f);
|
|
|
|
f=NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
len=ftell(f);
|
|
|
|
if (len==(SIZE_MAX>>1)) {
|
|
|
|
len=0;
|
|
|
|
fclose(f);
|
|
|
|
f=NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fseek(f,0,SEEK_SET)==-1) {
|
|
|
|
len=0;
|
|
|
|
fclose(f);
|
|
|
|
f=NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
sf=sf_open_virtual(&vio,mode,sfinfo,this);
|
2022-06-29 03:08:24 +00:00
|
|
|
if (sf!=NULL) fileMode=mode;
|
2022-06-28 07:00:08 +00:00
|
|
|
return sf;
|
|
|
|
}
|