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

Fixed audio and MIDI drivers; encode device names as CP_UTF8 #1325

Closed
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ if ( WIN32 OR CYGWIN )
endif()
endif ()
message ( STATUS "Targeting Windows Version ${windows-version}" )
add_definitions ( -D _UNICODE -D UNICODE )
add_definitions ( -D _WIN32_WINNT=${windows-version} )
add_definitions ( -D WINVER=${windows-version} )
list ( APPEND CMAKE_REQUIRED_DEFINITIONS "-DWINVER=${windows-version}" )
Expand Down
9 changes: 9 additions & 0 deletions doc/examples/fluidsynth_enumsettings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
* [Pedro López-Cabanillas <[email protected]>]
*/

#ifdef _WIN32
#include <windows.h>
#endif

#include <list>
#include <string>
#include <iostream>
Expand All @@ -23,6 +27,11 @@ int main(int argc, char**)
fluid_settings_t* settings = nullptr;
void* context = nullptr;

#ifdef _WIN32
SetConsoleOutputCP(CP_UTF8);
setvbuf(stdout, nullptr, _IONBF, 0);
#endif

std::cout << "C++ enum settings of FluidSynth v" << fluid_version_str() << std::endl;

if (argc > 1) {
Expand Down
8 changes: 4 additions & 4 deletions doc/fluidsettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ Developers:
<type>str</type>
<def>default</def>
<desc>
Selects the DirectSound (Windows) device to use.
Selects the DirectSound (Windows) device to use. Starting with 2.3.6 all device names are expected to be UTF8 encoded.
</desc>
</setting>
<setting>
Expand Down Expand Up @@ -705,7 +705,7 @@ Developers:
<type>str</type>
<def>default</def>
<desc>
Device to use for WASAPI driver output.
Device to use for WASAPI driver output. Starting with 2.3.6 all device names are expected to be UTF8 encoded.
</desc>
</setting>
<setting>
Expand All @@ -721,7 +721,7 @@ Developers:
<type>str</type>
<def>default</def>
<desc>
Device to use for WaveOut driver output.
Device to use for WaveOut driver output. Starting with 2.3.6 all device names are expected to be UTF8 encoded.
</desc>
</setting>
</audio>
Expand Down Expand Up @@ -804,7 +804,7 @@ Developers:
<name>winmidi.device</name>
<type>str</type>
<def>default</def>
<desc>The hardware device to use for Windows MIDI driver (not to be confused with the MIDI port). Multiple devices can be specified by a list of devices index separated by a semicolon (e.g "2;0", which is equivalent to one device with 32 MIDI channels).</desc>
<desc>The hardware device to use for Windows MIDI driver (not to be confused with the MIDI port). Multiple devices can be specified by a list of devices index separated by a semicolon (e.g "2;0", which is equivalent to one device with 32 MIDI channels). Starting with 2.3.6 all device names are expected to be UTF8 encoded.</desc>
</setting>
</midi>

Expand Down
3 changes: 3 additions & 0 deletions include/fluidsynth/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ extern "C" {
* // ...
* }
* @endcode
* All string settings are encoded in UTF-8. This includes the names
* of the audio and MIDI devices, exposed as setting options.
pedrolcl marked this conversation as resolved.
Show resolved Hide resolved
*
* @sa @ref CreatingSettings
*
* @{
Expand Down
33 changes: 26 additions & 7 deletions src/drivers/fluid_dsound.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,18 @@ typedef struct
BOOL CALLBACK
fluid_dsound_enum_callback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context)
{
fluid_settings_t *settings = (fluid_settings_t *) context;
fluid_settings_add_option(settings, "audio.dsound.device", (const char *)description);
fluid_settings_t *settings = (fluid_settings_t *)context;
char *name;
#if _UNICODE
int nsz = WideCharToMultiByte(CP_UTF8, 0, description, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz);
WideCharToMultiByte(CP_UTF8, 0, description, -1, name, nsz, 0, 0);
#else
name = FLUID_STRDUP(description);
#endif
FLUID_LOG(FLUID_DBG, "adding audio.dsound.device=%s", name);
fluid_settings_add_option(settings, "audio.dsound.device", name);
FLUID_FREE(name);

return TRUE;
}
Expand All @@ -121,11 +131,20 @@ fluid_dsound_enum_callback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPV
BOOL CALLBACK
fluid_dsound_enum_callback2(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context)
{
fluid_dsound_devsel_t *devsel = (fluid_dsound_devsel_t *) context;
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", description);

if(FLUID_STRCASECMP(devsel->devname, description) == 0)
{
fluid_dsound_devsel_t *devsel = (fluid_dsound_devsel_t *)context;
char *name;
#if _UNICODE
int nsz = WideCharToMultiByte(CP_UTF8, 0, description, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz);
WideCharToMultiByte(CP_UTF8, 0, description, -1, name, nsz, 0, 0);
#else
name = FLUID_STRDUP(description);
#endif
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", name);

if (FLUID_STRCASECMP(devsel->devname, name) == 0)
{
FLUID_FREE(name);
/* The device exists, return a copy of its GUID */
devsel->devGUID = FLUID_NEW(GUID);

Expand Down
12 changes: 6 additions & 6 deletions src/drivers/fluid_wasapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,9 @@ static void fluid_wasapi_register_callback(IMMDevice *dev, void *data)
int nsz;
char *name;

nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz + 1);
WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0);
nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz);
WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0);
fluid_settings_add_option(settings, "audio.wasapi.device", name);
FLUID_FREE(name);
}
Expand Down Expand Up @@ -828,9 +828,9 @@ static void fluid_wasapi_finddev_callback(IMMDevice *dev, void *data)
goto cleanup;
}

nsz = WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz + 1);
WideCharToMultiByte(CP_ACP, 0, var.pwszVal, -1, name, nsz, 0, 0);
nsz = WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, 0, 0, 0, 0);
name = FLUID_ARRAY(char, nsz);
WideCharToMultiByte(CP_UTF8, 0, var.pwszVal, -1, name, nsz, 0, 0);

if(!FLUID_STRCASECMP(name, d->name))
{
Expand Down
16 changes: 8 additions & 8 deletions src/drivers/fluid_waveout.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,7 @@ static DWORD WINAPI fluid_waveout_synth_thread(void *data)
void fluid_waveout_audio_driver_settings(fluid_settings_t *settings)
{
UINT n, nDevs = waveOutGetNumDevs();
#ifdef _UNICODE
char dev_name[MAXPNAMELEN];
#endif
char *dev_name;

fluid_settings_register_str(settings, "audio.waveout.device", "default", 0);
fluid_settings_add_option(settings, "audio.waveout.device", "default");
Expand All @@ -218,13 +216,15 @@ void fluid_waveout_audio_driver_settings(fluid_settings_t *settings)
if(res == MMSYSERR_NOERROR)
{
#ifdef _UNICODE
WideCharToMultiByte(CP_UTF8, 0, caps.szPname, -1, dev_name, MAXPNAMELEN, 0, 0);
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", dev_name);
fluid_settings_add_option(settings, "audio.waveout.device", dev_name);
int nsz = WideCharToMultiByte(CP_UTF8, 0, caps.szPname, -1, 0, 0, 0, 0);
dev_name = FLUID_ARRAY(char, nsz);
WideCharToMultiByte(CP_UTF8, 0, caps.szPname, -1, dev_name, nsz, 0, 0);
#else
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", caps.szPname);
fluid_settings_add_option(settings, "audio.waveout.device", caps.szPname);
dev_name = FLUID_STRDUP(caps.szPname);
#endif
FLUID_LOG(FLUID_DBG, "Testing audio device: %s", dev_name);
fluid_settings_add_option(settings, "audio.waveout.device", dev_name);
FLUID_FREE(dev_name);
}
}
}
Expand Down
20 changes: 12 additions & 8 deletions src/drivers/fluid_winmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,24 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
* @param dev_name, name of the device.
* @return the new device name (that must be freed when finish with it) or
* NULL if memory allocation error.
* Note: the returned name will be encoded in UTF8 if built with _UNICODE.
*/
static char *fluid_winmidi_get_device_name(int dev_idx, char *dev_name)
static char *fluid_winmidi_get_device_name(int dev_idx, TCHAR *input_dev_name)
{
char *new_dev_name;
char *dev_name;

int i = dev_idx;
size_t size = 0; /* index size */

#if _UNICODE
int nsz = WideCharToMultiByte(CP_UTF8, 0, input_dev_name, -1, 0, 0, 0, 0);
dev_name = FLUID_ARRAY(char, nsz);
WideCharToMultiByte(CP_UTF8, 0, input_dev_name, -1, dev_name, nsz, 0, 0);
#else
dev_name = FLUID_STRDUP(input_dev_name);
#endif

do
{
size++;
Expand All @@ -256,6 +266,7 @@ static char *fluid_winmidi_get_device_name(int dev_idx, char *dev_name)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
}
FLUID_FREE(dev_name);

return new_dev_name;
}
Expand Down Expand Up @@ -429,14 +440,7 @@ fluid_winmidi_parse_device_name(fluid_winmidi_driver_t *dev, char *dev_name)
break;
}

#ifdef _UNICODE
WCHAR wDevName[MAXPNAMELEN];
MultiByteToWideChar(CP_UTF8, 0, dev_name, -1, wDevName, MAXPNAMELEN);

str_cmp_res = wcsicmp(wDevName, new_dev_name);
#else
str_cmp_res = FLUID_STRCASECMP(dev_name, new_dev_name);
#endif

FLUID_LOG(FLUID_DBG, "Testing midi device \"%s\"", new_dev_name);
FLUID_FREE(new_dev_name);
Expand Down
29 changes: 24 additions & 5 deletions src/fluidsynth.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ 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 @@ -120,16 +123,25 @@ int process_o_cmd_line_option(fluid_settings_t *settings, char *optarg)
}

break;

case FLUID_STR_TYPE:
if(fluid_settings_setstr(settings, optarg, val) != FLUID_OK)

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:
fprintf(stderr, "Setting parameter '%s' not found\n", optarg);
return FLUID_FAILED;
Expand Down Expand Up @@ -391,6 +403,13 @@ 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
// console output will be utf-8
SetConsoleOutputCP(CP_UTF8);
// console input, too
SetConsoleCP(CP_UTF8);
#endif

#if SDL2_SUPPORT
// Tell SDL that it shouldn't intercept signals, otherwise SIGINT and SIGTERM won't quit fluidsynth
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
Expand Down
Loading