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

Costum soundfont is possible? #21

Closed
nnttoo opened this issue Apr 23, 2016 · 22 comments
Closed

Costum soundfont is possible? #21

nnttoo opened this issue Apr 23, 2016 · 22 comments
Labels

Comments

@nnttoo
Copy link

nnttoo commented Apr 23, 2016

thank you for sharing
can i load costum soundfont (how)?

@billthefarmer
Copy link
Owner

I don't thinks so. The soundfonts are built into the source code of the synthesizer.

@nnttoo
Copy link
Author

nnttoo commented Apr 23, 2016

i found this code in eas.h

EAS_LoadDLSCollection()

but i don understand c language,,

@billthefarmer
Copy link
Owner

billthefarmer commented Apr 23, 2016

I hadn't noticed that, it's not in the docs at https://github.com/android/platform_external_sonivox/tree/master/docs. To test it, you need to add some code to MidiDriver.java:

    public  native boolean loadDLS(String path);

with the other native methods. and add three bits of code to midi.cpp:

EAS_PUBLIC EAS_RESULT (*pEAS_LoadDLSCollection) (EAS_DATA_HANDLE pEASData,
                         EAS_HANDLE streamHandle,
                         EAS_FILE_LOCATOR locator);
// ...
// midi load dls
jboolean
Java_org_billthefarmer_mididriver_MidiDriver_loadDLS(JNIEnv *env,
                             jobject obj,
                             jstring jpath)
{
    jboolean isCopy;
    EAS_RESULT result;
    EAS_FILE file;

    if (pEASData == NULL || midiHandle == NULL)
    return JNI_FALSE;

    file.path = env->GetStringUTFChars(jpath, &isCopy);
    file.fd = 0;

    result = pEAS_LoadDLSCollection(pEASData, midiHandle, &file);

    env->ReleaseStringUTFChars(jpath, file.path);

    if (result != EAS_SUCCESS)
    return JNI_FALSE;

    return JNI_TRUE;
}
// ...
    pEAS_LoadDLSCollection = (EAS_PUBLIC EAS_RESULT (*)
                  (EAS_DATA_HANDLE pEASData,
                   EAS_HANDLE streamHandle,
                   EAS_FILE_LOCATOR locator))
        dlsym(libHandler, "EAS_LoadDLSCollection");
    if (!pEAS_LoadDLSCollection)
    {
        env->ThrowNew(linkageErrorClass,
              "EAS_LoadDLSCollection resolution failed");
        return -1;
    }

The last bit of code goes on the end of `JNI_OnLoad()``. This code builds OK, but I have no idea if it will work.
I found this: https://github.com/scummvm/scummvm/blob/master/audio/softsynth/eas.cpp when I was researching this driver. If has a bit of code in it than implies it might not work:

    // TODO doesn't seem to work with midi streams?
    if (ConfMan.hasKey("soundfont")) {
        const Common::String dls = ConfMan.get("soundfont");

        debug("loading DLS file '%s'", dls.c_str());

        EASFile f;
        memset(&f, 0, sizeof(EASFile));
        f.path = dls.c_str();

        res = _loadDLSFunc(_EASHandle, 0, &f);
        if (res)
            warning("error loading DLS file '%s': %d", dls.c_str(), res);
        else
            debug("DLS file loaded");
    }

@nnttoo
Copy link
Author

nnttoo commented Apr 24, 2016

I have tried to compile .so file, but still cannot, maybe I should learn it later, for now can you give .so file that has been compiled with the code above?

@billthefarmer
Copy link
Owner

billthefarmer commented Apr 24, 2016

OK
libmidi.zip

@nnttoo
Copy link
Author

nnttoo commented Apr 24, 2016

unfortunately it does not work, but thanks for your help.

java.lang.UnsatisfiedLinkError: Native method not found: org.billthefarmer.mididriver.MidiDriver.loadDLS:(Ljava/lang/String;)Z

@billthefarmer
Copy link
Owner

The DLS load code is in branch DLS on here. https://github.com/billthefarmer/mididriver/tree/DLS

@nnttoo
Copy link
Author

nnttoo commented Apr 25, 2016

i have tried this branch, no error, but loadDLS always return false,,
maybe you are right, it is not possible for now?

@billthefarmer
Copy link
Owner

billthefarmer commented Apr 26, 2016

I have updated the code because the EAS_LoadDLSCollection function here https://github.com/android/platform_external_sonivox/blob/master/arm-wt-22k/lib_src/eas_public.c does two different things.

EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
{
    EAS_FILE_HANDLE fileHandle;
    EAS_RESULT result;
    EAS_DLSLIB_HANDLE pDLS;

    if (pStream != NULL)
    {
        if (!EAS_StreamReady(pEASData, pStream))
            return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
    }

    /* open the file */
    if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
        return result;

    /* parse the file */
    result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
    EAS_HWCloseFile(pEASData->hwInstData, fileHandle);

    if (result == EAS_SUCCESS)
    {
        /* if a stream pStream is specified, point it to the DLS collection */
        if (pStream)
            result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);

        /* global DLS load */
        else
            result = VMSetGlobalDLSLib(pEASData, pDLS);
    }

    return result;
}

If the stream is null it does a global DLS load, so I have put another parameter in to do a global load to see if that might work.

 public native boolean loadDLS(String path, boolean global);

@billthefarmer
Copy link
Owner

DLS .aar files for Cody Eddings...
MidiDriver-DLS.aar.zip

@billthefarmer billthefarmer reopened this Jul 19, 2016
@CodyEddings
Copy link

I've been unable to load in my custom DLS. So far, i've tried:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Instantiate the driver.
        midiDriver = new MidiDriver();
        // Set the listener.
        midiDriver.setOnMidiStartListener(this);

       boolean test = false;
        String path = "android.resource://" + getPackageName() + "/" + R.raw.fury;
        midiDriver.loadDLS(path,test);
        if (test) {
            Toast.makeText(this, "DLS file loaded", Toast.LENGTH_SHORT);
        }
    }

It seems that "test" is always false. I've verified that I have a DLS file (fury.dls) located in the raw directory of my application. Am I using a correct implementation of loadDLS(string path, boolean global) or is it intended to be used differently?

@billthefarmer
Copy link
Owner

If you look at the comments above you can see that I put in the boolean parameter to determine whether to do a global load or not. I included an extract from the relevant code in the comment.

    if (global)
    result = pEAS_LoadDLSCollection(pEASData, NULL, &file);

    else
    result = pEAS_LoadDLSCollection(pEASData, midiHandle, &file);

    env->ReleaseStringUTFChars(jpath, file.path);

    if (result != EAS_SUCCESS)
    {
    LOG_E(LOG_TAG, "Load DLS collection failed: %ld", result);
    return JNI_FALSE;
    }

return JNI_TRUE;

The return value is the success/fail notification, the boolean global determines what bit of code gets executed. I suggest you try it both ways. I suggest you do...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Instantiate the driver.
        midiDriver = new MidiDriver();
        // Set the listener.
        midiDriver.setOnMidiStartListener(this);

       boolean success = false;
       boolean test = false;
        String path = "android.resource://" + getPackageName() + "/" + R.raw.fury;
        success = midiDriver.loadDLS(path,test);
        if (success) {
            Toast.makeText(this, "DLS file loaded (global)", Toast.LENGTH_SHORT);
        }
       success = false;
       test = true;
        String path = "android.resource://" + getPackageName() + "/" + R.raw.fury;
        success = midiDriver.loadDLS(path,test);
        if (success) {
            Toast.makeText(this, "DLS file loaded (not global)", Toast.LENGTH_SHORT);
        }
    }

@CodyEddings
Copy link

CodyEddings commented Jul 24, 2016

Unforunately, midiDriver.loadDLS(path,test); returned false whether it was run with true or false for the input global parmeter (called test). Are we out of options?

@loki666
Copy link

loki666 commented Aug 3, 2016

Using a file path in res/raw will never works since EAS will try to fopen() the path.
You need a file path that point to a file on the filesystem (ie: in /sdcard/).
Even like that I couldn't make it work. At best, it load the .DLS file OK, but it doesn't seem to actually use it.

@billthefarmer
Copy link
Owner

There is a further complication to this, around the time of Android 5.01, they changed the API for EAS_HWOpenFile(), and EAS_FILE_LOCATOR to use callbacks:

Author: Marco Nelissen <marcone@google.com>
Date:   Tue Dec 16 12:45:05 2014 -0800

    Use callbacks for I/O

    Instead of having the Sonivox engine directly open the file and
    use stdio to read from it, use caller-provided callbacks.

My code uses the old version. Now I have updated the driver to include the latest EAS Sonivox sources it's definitely not going to work. The driver doesn't support file IO, so it's not affected. If anyone is still interested in this, I could revert eas_hostmm.c and eas_types.h to the old version. I noticed a revision to DLS code in the commit history:

    Author: Eric Laurent <elaurent@google.com>
    Date:   Thu May 14 09:10:40 2015 -0700

    DLS parser: fix wave pool size check.

    Bug: 21132860.

@slesinger
Copy link

I'm interested to make it work. The default guitar sound is far from being usable. Thank you.

@billthefarmer
Copy link
Owner

You are welcome to fork the driver and have a go. The DLS branch contains the code I wrote to test and includes reverting eas_hostmm.c and eas_types.h to the old version as above.

@bmaupin
Copy link

bmaupin commented Feb 17, 2022

i found this code in eas.h

EAS_LoadDLSCollection()

but i don understand c language,,

It looks like EAS_LoadDLSCollection was removed with this commit message:

Remove unused code from midi engine

(https://android.googlesource.com/platform/external/sonivox/+/af41595537b044618234fe7dd9ebfcc652de1576%5E%21/#F1)

That might explain why it never worked 🤷‍♂️

@billthefarmer
Copy link
Owner

They removed a lot of unused by them code. I put the bits I use back in separately, but the DLS code was still in there when I was attempting to get it to work.

@M-HT
Copy link

M-HT commented May 29, 2023

If anyone is still interested in this, I recently made some changes in this fork of Sonivox EAS library to fix loading/using DLS files (at least some of them) using EAS_LoadDLSCollection. It shouldn't be difficult to adapt the changes to this project.
The relevant commits are:

@valentinev-celadon
Copy link

@billthefarmer Hi boss.
Will there be updates for connecting DLS?

@billthefarmer
Copy link
Owner

See the README, #43.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants