From 7ef86523265d10d9eabc05901194a4b4a5a0615b Mon Sep 17 00:00:00 2001 From: Yu Qing Date: Sun, 3 Oct 2021 18:15:57 +0800 Subject: [PATCH] fix windows related encoding problems (#984) --- src/drivers/fluid_wasapi.c | 8 +++--- src/fluidsynth.c | 59 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/drivers/fluid_wasapi.c b/src/drivers/fluid_wasapi.c index 3ff91d4b..7fc82098 100644 --- a/src/drivers/fluid_wasapi.c +++ b/src/drivers/fluid_wasapi.c @@ -788,9 +788,9 @@ static void fluid_wasapi_register_callback(IMMDevice *dev, void *data) int nsz; char *name; - nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0); + nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0); name = FLUID_ARRAY(char, nsz + 1); - WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0); + WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0); fluid_settings_add_option(settings, "audio.wasapi.device", name); FLUID_FREE(name); } @@ -827,9 +827,9 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data) goto cleanup; } - nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0); + nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0); name = FLUID_ARRAY(char, nsz + 1); - WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0); + WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0); if(!FLUID_STRCASECMP(name, d->name)) { diff --git a/src/fluidsynth.c b/src/fluidsynth.c index 6c1132f4..4661cbe0 100644 --- a/src/fluidsynth.c +++ b/src/fluidsynth.c @@ -156,6 +156,45 @@ print_pretty_int(int i) } } +#ifdef WIN32 +/* Function using win32 api to convert ANSI encoding string to UTF8 encoding string */ +static char* +win32_ansi_to_utf8(const char* ansi_null_terminated_string) +{ + LPWSTR u16_buf = NULL; + char *u8_buf = NULL; + fluid_return_val_if_fail(ansi_null_terminated_string != NULL, NULL); + do + { + int u16_count, u8_byte_count; + u16_count = MultiByteToWideChar(CP_ACP, 0, ansi_null_terminated_string, -1, NULL, 0); + if (u16_count == 0) + { + fprintf(stderr, "Failed to convert ANSI string to wide char string\n"); + break; + } + u16_buf = malloc(u16_count * sizeof(WCHAR)); + if (u16_buf == NULL) + { + fprintf(stderr, "Out of memory\n"); + break; + } + u16_count = MultiByteToWideChar(CP_ACP, 0, ansi_null_terminated_string, -1, u16_buf, u16_count); + u8_byte_count = WideCharToMultiByte(CP_UTF8, 0, u16_buf, u16_count, NULL, 0, NULL, NULL); + + u8_buf = malloc(u8_byte_count); + if (u8_buf == NULL) + { + fprintf(stderr, "Out of memory\n"); + break; + } + WideCharToMultiByte(CP_UTF8, 0, u16_buf, u16_count, u8_buf, u8_byte_count, NULL, NULL); + } while (0); + free(u16_buf); + return u8_buf; +} +#endif + typedef struct { int count; /* Total count of options */ @@ -896,14 +935,25 @@ int main(int argc, char **argv) /* load the soundfonts (check that all non options are SoundFont or MIDI files) */ for(i = arg1; i < argc; i++) { - if(fluid_is_midifile(argv[i])) + const char *u8_path = argv[i]; +#if defined(WIN32) + /* try to convert ANSI encoding path to UTF8 encoding path */ + char *u8_buf = win32_ansi_to_utf8(argv[i]); + if (u8_buf == NULL) + { + // error msg. already printed + goto cleanup; + } + u8_path = u8_buf; +#endif + if(fluid_is_midifile(u8_path)) { continue; } - if(fluid_is_soundfont(argv[i])) + if(fluid_is_soundfont(u8_path)) { - if(fluid_synth_sfload(synth, argv[i], 1) == -1) + if(fluid_synth_sfload(synth, u8_path, 1) == -1) { fprintf(stderr, "Failed to load the SoundFont %s\n", argv[i]); } @@ -912,6 +962,9 @@ int main(int argc, char **argv) { fprintf(stderr, "Parameter '%s' not a SoundFont or MIDI file or error occurred identifying it.\n", argv[i]); } +#if defined(WIN32) + free(u8_buf); +#endif } /* Try to load the default soundfont, if no soundfont specified */