BASS for Android

Started by Ian @ un4seen,

Ian @ un4seen

Yep, BASS_CTYPE_STREAM_AM means that an Android decoder is being used. You can use BASS_ChannelGetTags(BASS_TAG_AM_MIME) to find out what format it is. If it is MP3 then it probably has some junk at the start (before the MP3 data) that's preventing BASS detecting it. Raising the BASS_CONFIG_VERIFY setting (via BASS_SetConfig) will usually help in these cases.

johnbh3

Hi, On Android it compiles normally but when I click play it gives an error: Radio Cannot Be Started!

Android 32


1 : Library->Android->armeabi
   a : libbass.so
   b : libbass_aac.so   
   c : libbassflac.so
   Remote Path : library\lib\armeabi\
2 : Library->Android->x86
   a : libbass.so
   b : libbass_aac.so   
   c : libbassflac.so
   Remote Path : library\lib\x86\
3 : Library->Android->armeabi-v7a
   a : libbass.so
   b : libbass_aac.so   
   c : libbassflac.so
   Remote Path : library\lib\armeabi-v7a\

OK!


rrhh_fx

#1922
Quote from: Ian @ un4seenYep, BASS_CTYPE_STREAM_AM means that an Android decoder is being used. You can use BASS_ChannelGetTags(BASS_TAG_AM_MIME) to find out what format it is. If it is MP3 then it probably has some junk at the start (before the MP3 data) that's preventing BASS detecting it. Raising the BASS_CONFIG_VERIFY setting (via BASS_SetConfig) will usually help in these cases.

In this case, BASS_TAG_AM_MIME reports audio/mp4a-latm, and I have tried the BASS_CONFIG_VERIFY with multiple amounts of data to scan, but I guess that it is impossible decode a MP4 file as a MP3 :). Thanks a lot for sharing your knowledge and your support!!

rrhh_fx

Quote from: rrhh_fx
Quote from: Ian @ un4seenIt sounds like you want to get the level of the sound rather than a volume control? BASS_SetVolume/GetVolume (when available) provides the latter. One way you can get the level of the BASS output is to set a level-measuring DSP function on the output mix stream. For example, something like this:

int mixstream; // output mix stream
float mixlevel; // current level

BASS.DSPPROC MeasureLevel = new BASS.DSPPROC() {
public void DSPPROC(int handle, int channel, ByteBuffer buffer, int length, Object user) {
buffer.order(null); // little-endian
FloatBuffer ibuffer = buffer.asFloatBuffer();
float[] d = new float[length / 4]; // allocate array for data
ibuffer.get(d); // copy data from buffer to array
float level = 0;
for (int a = 0; a < length / 4; a++) {
if (level < Math.abs(d[a])) level = Math.abs(d[a]);
}
mixlevel = level;
}
};

mixstream = BASS.BASS_StreamCreate(0, 0, 0, BASS.STREAMPROC_DEVICE, null); // get output mix stream
BASS.BASS_ChannelSetDSP(mixstream, MeasureLevel, null, 0); // set level measuring DSP on it

That is exactly what I was trying to obtain. Regarding values of "mixlevel", how can they be interpreted? i.e. are they normalized from 0 to 1.0 and any higher value implies saturation?

Is there any way to get sepparated volume values for L-R channels in a stereo mix?

Thanks!

Hi, returning to this example, is there a way to remove an stream from the mixstream obtained from BASS.STREAMPROC_DEVICE. i.e., a stream that could not be affected by operations in mixstream, as measuring level or applying effects to mixstream. Thanks!

Ian @ un4seen

No, the DEVICE stream contains the final mix of all streams/channels that are currently playing on the device. If you need a mix of particular streams then you could use the BASSmix add-on to mix those, which will allow you to get the level and set DSP on them (ie. on the mixer handle) separate to the final mix.

sg

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

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

sg

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

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:

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

Thanks a lot for the info and help,
this works and is the best solution for my implementation!

Ian @ un4seen

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

Quote from: sgIt 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:
        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.

teq

#1933
Hi there!
I use Unity with BASS and it works ok, except some cases usually with Samsung devices.
Recently received a message from user that he switched his device to Galaxy a53 and "All tracks crackle and pop while playing visibly in the app gui interface.  Soon as I minimize the app it starts playing perfectly smooth".
I don't have Samsung device yet so maybe there are some suggestions how to solve this?
I suspect hat i should offer audio output methods in the settings(OpenSL, AudioTrack, AAduio).
Currently i use default behavior.

Ian @ un4seen

Do you know what Android version the device is running? It looks like the official latest is Android 8.0, which means OpenSLES would be the default output system used but AAudio may also be available. If you can send a test version of your app to the user, please try setting the BASS_CONFIG_ANDROID_AAUDIO option to 1 before calling BASS_Init to enable AAudio, and if that doesn't help, also try raising the BASS_CONFIG_DEV_BUFFER setting (again before BASS_Init).

teq

#1935
Quote from: Ian @ un4seenDo you know what Android version the device is running? It looks like the official latest is Android 8.0, which means OpenSLES would be the default output system used but AAudio may also be available. If you can send a test version of your app to the user, please try setting the BASS_CONFIG_ANDROID_AAUDIO option to 1 before calling BASS_Init to enable AAudio, and if that doesn't help, also try raising the BASS_CONFIG_DEV_BUFFER setting (again before BASS_Init).
Thanks for the feedback! Sorry, it was a typo, not Galaxy A5, it was Samsung Galaxy A53 5G with Android 13.
Can i change output method or BASS_CONFIG_DEV_BUFFER after BASS_Init, so if user would like to change this option several times for finding the best sound?

Ian @ un4seen

You will need to call BASS_Init again to apply the changes, but you can use the BASS_DEVICE_REINIT flag when doing so, to retain the existing channels/handles. You can also toggle the BASS_DEVICE_AUDIOTRACK flag that way, to enable/disable using AudioTrack output instead of AAudio or OpenSLES.

hexise

Hello,

I found a new problem when a user reported a file which my app cannot support.

It is a voicemail wav file, and after I test it, I found the encoding is PCM MU-LAW. Does BASS support this encoding?

I have tested that Android default music player can support this encoding. Am I missing any add-on to support it? If BASS does not support it, will it handover to Android to play it?

Currently from my testing, the format is not supported and when use BASS to parse the file, it throws BASS_ERROR_FORMAT error.

Thanks.

Ian @ un4seen

BASS doesn't have built-in support for mu-law, but it may be supported via the OS's codecs, eg. it is on Windows. Checking an mu-law WAV file on Android just now, it is detected as "g711-mlaw" by Android's media codecs but then they fail to parse/decode the data. Android's list of supported formats only mentions linear PCM, so it may be that mu-law isn't supported:

   https://developer.android.com/media/platform/supported-formats

OnePeople

Hi.
How play file in AudioManager.STREAM_RING?