From ddcae478d4a85a540f132ed38333776c5b9f95d0 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Tue, 29 May 2018 17:37:22 +0900 Subject: [PATCH] Fix sample file loading on Windows --- include/DrumSynth.h | 12 +++++++----- include/SampleBuffer.h | 6 +++--- src/core/DrumSynth.cpp | 24 +++++++++++++++--------- src/core/SampleBuffer.cpp | 35 +++++++++++++++++++---------------- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/include/DrumSynth.h b/include/DrumSynth.h index 22d7d3071..f7e9b1d4c 100644 --- a/include/DrumSynth.h +++ b/include/DrumSynth.h @@ -30,22 +30,24 @@ #include #include "lmms_basics.h" +class QString; + class DrumSynth { public: DrumSynth() {}; - int GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels, sample_rate_t Fs); + int GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs); private: float LoudestEnv(void); int LongestEnv(void); void UpdateEnv(int e, long t); - void GetEnv(int env, const char *sec, const char *key, const char *ini); + void GetEnv(int env, const char *sec, const char *key, QString ini); float waveform(float ph, int form); - int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file); - int GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file); - float GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file); + int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file); + int GetPrivateProfileInt(const char *sec, const char *key, int def, QString file); + float GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file); }; diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 66f4ec873..3acf2c10b 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -270,15 +270,15 @@ private: void convertIntToFloat ( int_sample_t * & _ibuf, f_cnt_t _frames, int _channels); void directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _channels); - f_cnt_t decodeSampleSF( const char * _f, sample_t * & _buf, + f_cnt_t decodeSampleSF( QString _f, sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); #ifdef LMMS_HAVE_OGGVORBIS - f_cnt_t decodeSampleOGGVorbis( const char * _f, int_sample_t * & _buf, + f_cnt_t decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); #endif - f_cnt_t decodeSampleDS( const char * _f, int_sample_t * & _buf, + f_cnt_t decodeSampleDS( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index fd0695557..e1fb77793 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -26,11 +26,13 @@ #include "DrumSynth.h" -#include +#include #include #include //sin(), exp(), etc. +#include + #ifdef LMMS_BUILD_WIN32 #define powf pow #endif @@ -112,7 +114,7 @@ void DrumSynth::UpdateEnv(int e, long t) } -void DrumSynth::GetEnv(int env, const char *sec, const char *key, const char *ini) +void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini) { char en[256], s[8]; int i=0, o=0, ep=0; @@ -162,9 +164,9 @@ float DrumSynth::waveform(float ph, int form) } -int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file) +int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file) { - ifstream is; + stringstream is; bool inSection = false; char *line; char *k, *b; @@ -172,7 +174,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c line = (char*)malloc(200); - is.open (file, ifstream::in); + // Use QFile to handle unicode file name on Windows + // Previously we used ifstream directly + QFile f(file); + f.open(QIODevice::ReadOnly); + QByteArray dat = f.readAll().constData(); + is.str(string(dat.constData(), dat.size())); while (is.good()) { if (!inSection) { @@ -218,13 +225,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c strncpy(buffer, def, size); } - is.close(); free(line); return len; } -int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file) +int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, QString file) { char tmp[16]; int i=0; @@ -235,7 +241,7 @@ int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, c return i; } -float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file) +float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file) { char tmp[16]; float f=0.f; @@ -252,7 +258,7 @@ float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float // an associative array or something once we have a datastructure to load in to. // llama -int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels, sample_rate_t Fs) +int DrumSynth::GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs) { //input file char sec[32]; diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 5fc640cb6..86f8fd55c 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -187,11 +187,6 @@ void SampleBuffer::update( bool _keep_settings ) else if( !m_audioFile.isEmpty() ) { QString file = tryToMakeAbsolute( m_audioFile ); -#ifdef LMMS_BUILD_WIN32 - char * f = qstrdup( file.toLocal8Bit().constData() ); -#else - char * f = qstrdup( file.toUtf8().constData() ); -#endif int_sample_t * buf = NULL; sample_t * fbuf = NULL; ch_cnt_t channels = DEFAULT_CHANNELS; @@ -205,10 +200,13 @@ void SampleBuffer::update( bool _keep_settings ) } else { + // Use QFile to handle unicode file names on Windows + QFile f(file); + f.open(QIODevice::ReadOnly); SNDFILE * snd_file; SF_INFO sf_info; sf_info.format = 0; - if( ( snd_file = sf_open( f, SFM_READ, &sf_info ) ) != NULL ) + if( ( snd_file = sf_open_fd( f.handle(), SFM_READ, &sf_info, false ) ) != NULL ) { f_cnt_t frames = sf_info.frames; int rate = sf_info.samplerate; @@ -218,6 +216,7 @@ void SampleBuffer::update( bool _keep_settings ) } sf_close( snd_file ); } + f.close(); } if( !fileLoadError ) @@ -228,28 +227,26 @@ void SampleBuffer::update( bool _keep_settings ) // decoder first if filename extension matches "ogg" if( m_frames == 0 && fileInfo.suffix() == "ogg" ) { - m_frames = decodeSampleOGGVorbis( f, buf, channels, samplerate ); + m_frames = decodeSampleOGGVorbis( file, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { - m_frames = decodeSampleSF( f, fbuf, channels, + m_frames = decodeSampleSF( file, fbuf, channels, samplerate ); } #ifdef LMMS_HAVE_OGGVORBIS if( m_frames == 0 ) { - m_frames = decodeSampleOGGVorbis( f, buf, channels, + m_frames = decodeSampleOGGVorbis( file, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { - m_frames = decodeSampleDS( f, buf, channels, + m_frames = decodeSampleDS( file, buf, channels, samplerate ); } - - delete[] f; } if ( m_frames == 0 || fileLoadError ) // if still no frames, bail @@ -405,7 +402,7 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, -f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, +f_cnt_t SampleBuffer::decodeSampleSF(QString _f, sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) @@ -416,7 +413,11 @@ f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, f_cnt_t frames = 0; bool sf_rr = false; - if( ( snd_file = sf_open( _f, SFM_READ, &sf_info ) ) != NULL ) + + // Use QFile to handle unicode file names on Windows + QFile f(_f); + f.open(QIODevice::ReadOnly); + if( ( snd_file = sf_open_fd( f.handle(), SFM_READ, &sf_info, false ) ) != NULL ) { frames = sf_info.frames; @@ -442,6 +443,8 @@ f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, "sample %s: %s", _f, sf_strerror( NULL ) ); #endif } + f.close(); + //write down either directly or convert i->f depending on file type if ( frames > 0 && _buf != NULL ) @@ -507,7 +510,7 @@ long qfileTellCallback( void * _udata ) -f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, +f_cnt_t SampleBuffer::decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) @@ -603,7 +606,7 @@ f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, -f_cnt_t SampleBuffer::decodeSampleDS( const char * _f, +f_cnt_t SampleBuffer::decodeSampleDS( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate )