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

Cannot load files containing unicode. #18

Closed
zX3no opened this issue Oct 13, 2021 · 11 comments
Closed

Cannot load files containing unicode. #18

zX3no opened this issue Oct 13, 2021 · 11 comments

Comments

@zX3no
Copy link

zX3no commented Oct 13, 2021

When trying to load a file containing unicode characters I get the error Internal(FileNotFound).

let mut wav = audio::Wav::default();

wav.load(Path::new("覆.flac"))?;
//Crashes here ^     

I'm pretty sure this has something to do with const char * not supporting unicode, so I'm not sure if this is a problem with the bindings.

I've been able to alleviate the problem on Windows by getting the short path and using that instead.

let p = "覆.flac";
//convert path to null terminated string
let long_path: Vec<u16> = p.encode_utf16().chain(Some(0)).collect();
//get length of short path
let len = GetShortPathNameW(long_path.as_ptr(), null_mut(), 0);

let mut short_path = vec![0; len as usize];

//get short path
GetShortPathNameW(long_path.as_ptr(), short_path.as_mut_ptr(), len);

//convert short path to string
let mut path = String::from_utf16(&short_path).unwrap();
//remove null terminator
path.pop();

assert_eq!(path, "3342~1.FLA");

Edit:
Short paths only seem to work on certain files, It might have something to do with file permissions. All I can say is that it's super broken.

@MoAlyousef
Copy link
Owner

Can you try using the raw bindings directly by importing soloud-sys:

use soloud_sys::soloud::*;

fn main() {
    unsafe {
        let sl = Soloud_create();
        Soloud_init(sl);
        Soloud_setGlobalVolume(sl, 3.0);
    
        let wav = Wav_create();
    
        let ret = Wav_load(wav, "覆.flac\0".as_ptr() as _);
    
        dbg!(ret);
        
        Soloud_play(sl, wav);
        while Soloud_getVoiceCount(sl) > 0 {
            // calls to play are non-blocking, so we put the thread to sleep
            std::thread::sleep(std::time::Duration::from_millis(100));
        }
    }
}

What does this program print?

@zX3no
Copy link
Author

zX3no commented Oct 13, 2021

[src\main.rs:14] ret = 2

@MoAlyousef
Copy link
Owner

It's the file not found error. So it's from soloud itself. I currently tried with a similar program on my MacOS and unicode file names work correctly.
I'll try on a windows machine later.

@zX3no
Copy link
Author

zX3no commented Oct 13, 2021

Okay cool, thanks for the help

@MoAlyousef
Copy link
Owner

So I just tried this on a Windows machine, and it's a soloud issue on Windows, unicode paths work fine on MacOS and Linux. I created a repro in C++:

#include <stdio.h>

#include "soloud.h"
#include "soloud_wav.h"
#include "soloud_thread.h"

int main() {
    SoLoud::Soloud sl;
    SoLoud::Wav wav;
    sl.init();

    auto ret = wav.load("覆.mp3");
    printf("%d\n", ret);

	sl.play(wav);

	while (sl.getActiveVoiceCount() > 0) {
		SoLoud::Thread::sleep(100);
	}

	sl.deinit();

	return 0;
}

P.S. I changed the extension to mp3 since that's the file I'm trying out with.

@MoAlyousef
Copy link
Owner

MoAlyousef commented Oct 13, 2021

It should be working now in master since I added the utf-8 compile flag in the CMakeLists.txt:

add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

@MoAlyousef
Copy link
Owner

Can you recheck against the master branch:

[dependencies]
soloud = { git = "https://github.com/moalyousef/soloud-rs" }

@zX3no
Copy link
Author

zX3no commented Oct 14, 2021

This seems to have fixed it, but only if you have the UTF-8 beta enabled.
I tried without it first and got the same error.

I only vaguely remembered that windows has this option and that it's off by default.

@MoAlyousef
Copy link
Owner

That is inconvenient. The only workaround I can think of is to use load_mem when file loading fails.

@MoAlyousef
Copy link
Owner

So I've added the workaround to the lib. If you can check against the master branch.
load() currently checks if the path is ascii on windows, if not it internally uses load_mem

@zX3no
Copy link
Author

zX3no commented Oct 15, 2021

Thanks, this has fixed the issue for me.

@zX3no zX3no closed this as completed Oct 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants