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

Convert fluidsynth CLI arguments #1421

Merged
merged 2 commits into from
Nov 6, 2024
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 src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ if ( TARGET PipeWire::PipeWire AND PIPEWIRE_SUPPORT ) # because pw_init() etc.
target_link_libraries ( fluidsynth PRIVATE PipeWire::PipeWire )
endif()

if ( MINGW )
target_link_options( fluidsynth PRIVATE -municode )
endif()

if ( MACOSX_FRAMEWORK )
install ( TARGETS fluidsynth libfluidsynth
EXPORT FluidSynthTargets
Expand Down
125 changes: 46 additions & 79 deletions src/fluidsynth.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ void print_help(fluid_settings_t *settings);
void print_welcome(void);
void print_configure(void);
void fluid_wasapi_device_enumerate(void);
#ifdef _WIN32
static char* win32_ansi_to_utf8(const char* ansi_null_terminated_string);
#endif

/*
* the globals
Expand Down Expand Up @@ -126,20 +123,11 @@ int process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)

case FLUID_STR_TYPE: {
char *u8_val = val;
#if defined(_WIN32)
u8_val = win32_ansi_to_utf8(val);
#endif
if(fluid_settings_setstr(settings, optarg, u8_val) != FLUID_OK)
{
fprintf(stderr, "Failed to set string parameter '%s'\n", optarg);
#if defined(_WIN32)
free(u8_val);
#endif
return FLUID_FAILED;
}
#if defined(_WIN32)
free(u8_val);
#endif
break;
}
default:
Expand Down Expand Up @@ -167,45 +155,6 @@ 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 */
Expand Down Expand Up @@ -376,9 +325,13 @@ fast_render_loop(fluid_settings_t *settings, fluid_synth_t *synth, fluid_player_
15)create the audio driver (i.e synthesis thread) and a synchronous user
shell if interactive.
*/
#if defined(_WIN32)
int wmain(int argc, wchar_t **wargv)
#else
int main(int argc, char **argv)
#endif
{
fluid_settings_t *settings;
fluid_settings_t *settings = NULL;
int result = -1;
int arg1 = 1;
char buf[512];
Expand All @@ -403,11 +356,40 @@ int main(int argc, char **argv)
int fast_render = 0;
static const char optchars[] = "a:C:c:dE:f:F:G:g:hijK:L:lm:nO:o:p:QqR:r:sT:Vvz:";

#ifdef _WIN32
#if defined(_WIN32)
char **argv = NULL;
// console output will be utf-8
SetConsoleOutputCP(CP_UTF8);
// console input, too
SetConsoleCP(CP_UTF8);
// conversion of wchar_t (UTF-16) arguments to char (UTF-8)
if ((argv = (char **) calloc( argc, sizeof(char *) )) == NULL)
{
fprintf(stderr, "Out of memory\n");
goto cleanup;
}
else
{
for (i = 0; i < argc; ++i)
{
int u8_count = 0;
if (1 > (u8_count = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wargv[i], -1, NULL, 0, NULL, NULL)))
Copy link
Member

Choose a reason for hiding this comment

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

@pedrolcl We have a minor oversight: WC_ERR_INVALID_CHARS is not available for WindowsXP, causing the CI to fail:
https://dev.azure.com/tommbrt/tommbrt/_build/results?buildId=10875&view=logs&j=ae601b3d-8756-52a4-4bcc-59c4d24c3f8c&t=1e42d489-b2c6-5e77-903e-6d797975357c&l=653

JJC needs WindowsXP compatibility. I haven't seen this earlier, because the build failed due to an issue in libinstpatch related to your bump of libsndfile min version: swami/libinstpatch#78

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then, the only option is to replace the WC_ERR_INVALID_CHARS flag by 0.

Copy link
Member

Choose a reason for hiding this comment

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

Would something like

#ifndef WC_ERR_INVALID_CHARS
#define WC_ERR_INVALID_CHARS 0
#endif

make sense, so that at least on modern Windows it reports a proper error?

{
fprintf(stderr, "Failed to convert wide char string to UTF8\n");
goto cleanup;
}
else if ((argv[i] = (char *) calloc(u8_count, sizeof(char))) == NULL)
{
fprintf(stderr, "Out of memory\n");
goto cleanup;
}
else if (u8_count != WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wargv[i], -1, argv[i], u8_count, NULL, NULL))
{
fprintf(stderr, "Failed to convert wide char string to UTF8\n");
goto cleanup;
}
}
}
#endif

#if SDL2_SUPPORT
Expand Down Expand Up @@ -939,16 +921,6 @@ int main(int argc, char **argv)
for(i = arg1; i < argc; 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;
Expand All @@ -965,9 +937,6 @@ 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 */
Expand Down Expand Up @@ -1023,16 +992,6 @@ int main(int argc, char **argv)
for(i = arg1; i < argc; 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((u8_path[0] != '-') && fluid_is_midifile(u8_path))
{
if(player == NULL)
Expand All @@ -1054,9 +1013,6 @@ int main(int argc, char **argv)

fluid_player_add(player, u8_path);
}
#if defined(_WIN32)
free(u8_buf);
#endif
}

/* try to load and execute the user or system configuration file */
Expand Down Expand Up @@ -1204,6 +1160,17 @@ int main(int argc, char **argv)
delete_fluid_synth(synth);
delete_fluid_settings(settings);

#ifdef _WIN32
if (argv != NULL)
{
for (i = 0; i < argc; ++i)
{
free(argv[i]);
}
free(argv);
}
#endif

return result;
}

Expand Down
Loading