Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some encoding issues (mostly on Windows) #4401

Merged
merged 6 commits into from
Jul 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/AudioFileDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class AudioFileDevice : public AudioDevice
return m_outputFile.isOpen();
}

inline int outputFileHandle() const
{
return m_outputFile.handle();
}

private:
QFile m_outputFile;
Expand Down
12 changes: 7 additions & 5 deletions include/DrumSynth.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@
#include <stdint.h>
#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);

};

Expand Down
5 changes: 5 additions & 0 deletions include/ImportFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class EXPORT ImportFilter : public Plugin
return m_file.read( _data, _len );
}

inline QByteArray readAllData()
{
return m_file.readAll();
}

inline void ungetChar( char _ch )
{
m_file.ungetChar( _ch );
Expand Down
72 changes: 72 additions & 0 deletions include/IoHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* IoHelper.h - helper functions for file I/O
*
* Copyright (c) 2018 Hyunjin Song <tteu.ingog/at/gmail.com>
*
* This file is part of LMMS - https://lmms.io
*
* 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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/


#include "lmmsconfig.h"

#include <cstdio>


#ifdef _WIN32
#include <windows.h>

std::wstring toWString(const std::string& s)
{
std::wstring ret;
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(),
s.length(), nullptr, 0);
if (len == 0)
{
return ret;
}
ret.resize(len);
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.length(), &ret[0], len);
return ret;
}
#endif

#ifdef LMMS_BUILD_WIN32
#include <io.h>
#define F_OPEN_UTF8(a, b) _wfopen(toWString(a).data(), L##b)
#else
#ifdef LMMS_HAVE_UNISTD_H
#include <unistd.h>
#endif
#define F_OPEN_UTF8(a, b) fopen((a).data(), b)
#endif

int fileToDescriptor(FILE* f, bool closeFile = true)
{
int fh;
if (f == NULL) {return -1;}

#ifdef LMMS_BUILD_WIN32
fh = _dup(_fileno(f));
#else
fh = dup(fileno(f));
#endif

if (closeFile) {fclose(f);}
return fh;
}
6 changes: 3 additions & 3 deletions include/SampleBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,15 @@ public slots:
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 );

Expand Down
11 changes: 8 additions & 3 deletions plugins/MidiImport/MidiImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@
#include <QDomDocument>
#include <QDir>
#include <QApplication>
#include <QFile>
#include <QMessageBox>
#include <QProgressDialog>

#include <sstream>

#include "MidiImport.h"
#include "TrackContainer.h"
#include "InstrumentTrack.h"
Expand Down Expand Up @@ -279,8 +282,6 @@ class smfMidiChannel

bool MidiImport::readSMF( TrackContainer* tc )
{
QString filename = file().fileName();
closeFile();

const int preTrackSteps = 2;
QProgressDialog pd( TrackContainer::tr( "Importing MIDI-file..." ),
Expand All @@ -291,7 +292,11 @@ bool MidiImport::readSMF( TrackContainer* tc )

pd.setValue( 0 );

Alg_seq_ptr seq = new Alg_seq(filename.toLocal8Bit(), true);
std::stringstream stream;
QByteArray arr = readAllData();
stream.str(std::string(arr.constData(), arr.size()));

Alg_seq_ptr seq = new Alg_seq(stream, true);
seq->convert_to_beats();

pd.setMaximum( seq->tracks() + preTrackSteps );
Expand Down
6 changes: 3 additions & 3 deletions plugins/stk/mallets/mallets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch,
{
Stk::setSampleRate( _sample_rate );
Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath()
.toLatin1().constData() );
.toLocal8Bit().constData() );
#ifndef LMMS_DEBUG
Stk::showWarnings( false );
#endif
Expand Down Expand Up @@ -670,7 +670,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch,
{
Stk::setSampleRate( _sample_rate );
Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath()
.toLatin1().constData() );
.toLocal8Bit().constData() );
#ifndef LMMS_DEBUG
Stk::showWarnings( false );
#endif
Expand Down Expand Up @@ -718,7 +718,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch,
{
Stk::setSampleRate( _sample_rate );
Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath()
.toLatin1().constData() );
.toLocal8Bit().constData() );
#ifndef LMMS_DEBUG
Stk::showWarnings( false );
#endif
Expand Down
23 changes: 12 additions & 11 deletions plugins/vst_base/RemoteVstPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct ERect
#include "lmms_basics.h"
#include "Midi.h"
#include "communication.h"
#include "IoHelper.h"

#include "VstSyncData.h"

Expand Down Expand Up @@ -678,9 +679,9 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )



static void close_check( int fd )
static void close_check( FILE* fp )
{
if( close( fd ) )
if( fclose( fp ) )
{
perror( "close" );
}
Expand Down Expand Up @@ -790,7 +791,7 @@ void RemoteVstPlugin::destroyEditor()

bool RemoteVstPlugin::load( const std::string & _plugin_file )
{
if( ( m_libInst = LoadLibrary( _plugin_file.c_str() ) ) == NULL )
if( ( m_libInst = LoadLibraryW( toWString(_plugin_file).c_str() ) ) == NULL )
{
// give VstPlugin class a chance to start 32 bit version of RemoteVstPlugin
if( GetLastError() == ERROR_BAD_EXE_FORMAT )
Expand Down Expand Up @@ -1072,13 +1073,13 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file )
const int len = pluginDispatch( 23, 0, 0, &chunk );
if( len > 0 )
{
int fd = open( _file.c_str(), O_WRONLY | O_BINARY );
if ( ::write( fd, chunk, len ) != len )
FILE* fp = F_OPEN_UTF8( _file, "wb" );
if ( fwrite( chunk, len, 1, fp ) != len )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only spotted this now: fwritereturns the count of elements successfully written, so in this case it will return 1 on success, not len. Therefore this condition is always leading to a false error message on success (except when coincidentally len == 1).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Changed to fwrite( chunk, 1, len, fp ) in 0f3b41f.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also synced into master via 170a46e.

{
fprintf( stderr,
"Error saving chunk to file.\n" );
}
close_check( fd );
close_check( fp );
}
}
}
Expand Down Expand Up @@ -1237,7 +1238,7 @@ void RemoteVstPlugin::savePreset( const std::string & _file )
if (!isPreset &&!chunky) uIntToFile = (unsigned int) m_plugin->numPrograms;
pBank->numPrograms = endian_swap( uIntToFile );

FILE * stream = fopen( _file.c_str(), "w" );
FILE * stream = F_OPEN_UTF8( _file, "w" );
fwrite ( pBank, 1, 28, stream );
fwrite ( progName, 1, isPreset ? 28 : 128, stream );
if ( chunky ) {
Expand Down Expand Up @@ -1289,7 +1290,7 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
unsigned int * pLen = new unsigned int[ 1 ];
unsigned int len = 0;
sBank * pBank = (sBank*) new char[ sizeof( sBank ) ];
FILE * stream = fopen( _file.c_str(), "r" );
FILE * stream = F_OPEN_UTF8( _file, "r" );
if ( fread ( pBank, 1, 56, stream ) != 56 )
{
fprintf( stderr, "Error loading preset file.\n" );
Expand Down Expand Up @@ -1390,12 +1391,12 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len )
{
char * chunk = new char[_len];

const int fd = open( _file.c_str(), O_RDONLY | O_BINARY );
if ( ::read( fd, chunk, _len ) != _len )
FILE* fp = F_OPEN_UTF8( _file, "rb" );
if ( fread( chunk, 1, _len, fp ) != _len )
{
fprintf( stderr, "Error loading chunk from file.\n" );
}
close_check( fd );
close_check( fp );

pluginDispatch( effSetChunk, 0, _len, chunk );

Expand Down
19 changes: 12 additions & 7 deletions plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,13 @@
#include <sstream>
#include <cstdarg>
#include <zlib.h>
#include "lmmsconfig.h"
#include "../globals.h"
#include "Util.h"

// Include LMMS headers
#include "lmmsconfig.h"
#include "IoHelper.h"


struct XmlData
{
Expand Down Expand Up @@ -193,11 +196,12 @@ int QtXmlWrapper::dosavefile(const char *filename,
int compression,
const char *xmldata) const
{
FILE *file = F_OPEN_UTF8(std::string(filename), "w");
if(file == NULL) {
return -1;
}

if(compression == 0) {
FILE *file;
file = fopen(filename, "w");
if(file == NULL)
return -1;
fputs(xmldata, file);
fclose(file);
}
Expand All @@ -210,7 +214,7 @@ int QtXmlWrapper::dosavefile(const char *filename,
snprintf(options, 10, "wb%d", compression);

gzFile gzfile;
gzfile = gzopen(filename, options);
gzfile = gzdopen(fileToDescriptor(file), options);
if(gzfile == NULL)
return -1;
gzputs(gzfile, xmldata);
Expand Down Expand Up @@ -313,7 +317,8 @@ int QtXmlWrapper::loadXMLfile(const std::string &filename)
char *QtXmlWrapper::doloadfile(const std::string &filename) const
{
char *xmldata = NULL;
gzFile gzfile = gzopen(filename.c_str(), "rb");

gzFile gzfile = gzdopen(fileToDescriptor(F_OPEN_UTF8(filename, "rb")), "rb");

if(gzfile != NULL) { //The possibly compressed file opened
std::stringstream strBuf; //reading stream
Expand Down
Loading