Author Topic: BASS for Android  (Read 785300 times)

sg

  • Posts: 4
Re: BASS for Android
« Reply #1925 on: 20 Jan '23 - 19:56 »
Hi,
what would be the best option to load (user selected) soundfonts on Android?

I use the ACTION_OPEN_DOCUMENT Intent to let the user select the soundfont.
As a result I get an Uri object from which I can retrieve a ParcelFileDescriptor object.

Is there any way to convert this Uri / ParcelFileDescriptor into a parameter that is compatible with the available BASS_MIDI_FontInit methods?


(I don't want to copy the whole soundfont into the app's storage.
This is my current temporary solution, because I have direct access to the file and file name there, but isn't perfect for very large soundfonts.
And loading it through a ByteBuffer results in an OutOfMemoryError for larger files)


Thanks!

Ian @ un4seen

  • Administrator
  • Posts: 24797
Re: BASS for Android
« Reply #1926 on: 23 Jan '23 - 16:32 »
When you don't have a filename to give, you can use BASS_MIDI_FontInitUser with BASS_FILEPROCS callback functions instead of BASS_MIDI_FontInit to load a soundfont. BASSMIDI will call your functions to get the file data as needed then.

sg

  • Posts: 4
Re: BASS for Android
« Reply #1927 on: 23 Jan '23 - 20:43 »
Ok thanks, I will try that!

sg

  • Posts: 4
Re: BASS for Android
« Reply #1928 on: 23 Jan '23 - 21:48 »
It seems that I am not able to implement the callback function FILESEEKPROC because InputStreams which I can open from URIs do not support seeking.

Apparently the only option to load user selected soundfonts is to copy them into a new file (in the app's storage), which is not perfect, but it works.

(If I'm wrong or there are other ways, feel free to share them, thanks!)

Ian @ un4seen

  • Administrator
  • Posts: 24797
Re: BASS for Android
« Reply #1929 on: 24 Jan '23 - 13:49 »
If you use a FileInputStream instead of InputStream then you should be able to seek via the getChannel().position method.

Looking at BASS_MIDI_FontInit again now, I think it should actually already support ParcelFileDescriptor, but the BASSMIDI.JAVA file doesn't contain the required overload yet. Please try adding this line to that file:

Code: [Select]
public static native int BASS_MIDI_FontInit(ParcelFileDescriptor file, int flags);

Also "import android.os.ParcelFileDescriptor;" at the top. And then try using your ParcelFileDescriptor with BASS_MIDI_FontInit.

sg

  • Posts: 4
Re: BASS for Android
« Reply #1930 on: 24 Jan '23 - 19:58 »
Thanks a lot for the info and help,
this works and is the best solution for my implementation!

Ian @ un4seen

  • Administrator
  • Posts: 24797
Re: BASS for Android
« Reply #1931 on: 25 Jan '23 - 13:17 »
Good to hear the BASSMIDI.JAVA update got things working for you. I have now put an updated BASSMIDI.JAVA file in the Android BASSMIDI package. Note a ParcelFileDescriptor overload is also available for BASS_MIDI_StreamCreateFile.

gicci

  • Posts: 94
Re: BASS for Android
« Reply #1932 on: 31 Jan '23 - 13:28 »
It seems that I am not able to implement the callback function FILESEEKPROC because InputStreams which I can open from URIs do not support seeking.

Apparently the only option to load user selected soundfonts is to copy them into a new file (in the app's storage), which is not perfect, but it works.

(If I'm wrong or there are other ways, feel free to share them, thanks!)

It seems that Ian solved your problem, but anyway I was able to implement a BASS_FILEPROCS that reads from a file the user selected with SAF. You should have done something like this:
Code: [Select]
        ContentResolver resolver = getApplication().getContentResolver();
        ParcelFileDescriptor parcelFileDescriptor = resolver.openFileDescriptor(document.getUri(), "r");
        fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        FileChannel channel = new FileInputStream(fileDescriptor).getChannel();
You can then use the FileChannel to read the data and on it the position() operation should work. Be sure to store the fileDescriptor in a variable of the object to retain it: if it gets garbage collected the channel will be closed.

The difficult thing is to open a SFZ file because you need to fix the paths, but also this can be done.