BASS for iOS (iPhone/iPad)

Started by Ian @ un4seen,

Ryota

Hi Ian,

The URL obtained by getTemporaryLink of Dropbox API could be used for streaming play by BASS_StreamCreateURL.

Recently, as shown in the URL below, the Content length is no longer returned due to a specification change on the Dropbox side, so streaming play has become impossible.

https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Dropbox-stopped-returning-Content-length-in-the-response-headers/td-p/575948

Is there any solution for streaming the Dropbox URL?

Ian @ un4seen

BASS_StreamCreateURL should be able to handle streaming files without a "Content-Length" header. It will automatically apply the BASS_STREAM_BLOCK flag then, like with a Shoutcast/Icecast stream. Please PM me an example problematic URL and I'll check what's happening.

Piero

Hi Ian,
I have a problem using BASS in my iOS app.
The target set in the project is from iOS 11. The version of BASS used is the last available inserted according to guide.
When I run on a device with iOS 11 or 12, the app crashes in BASS_ChannelPlay, while on iOS 13 everything is ok.

I ran various tests and tried on an empty project.
This is the code:

BASS_Init(-1, 44100, 0, nil, nil);
let channel = BASS_StreamCreateURL(streamURL, 0, 0, nil, nil);
BASS_ChannelPlay(channel, false)


If I run BASS_ErrorGetCode() after each line, the error returned is always 0.

Is there any BASS compatibility issue with iOS older than 13?

Thanks

Ian @ un4seen

Please post or send me the crash log from the device to have a look at. Also, is the problem only happening with a specific URL or file format, or all of them? Does it happen if you use BASS_StreamCreateFile to play a local file instead? If it is only happening with a private URL, you can PM it to me.

mdaskal

Hi,
I am trying to implement a custom Instrument AudioUnit to encapsulate the BASS Midi library.
It would basically behave as a sampler, receiving midi events and throwing the sample data (BASS_ChannelGetData) to the AudioUnit's output.

Here is the basic BASS implementation I did:
BASS_Init(-1, 44100, 0, 0, NULL);
stream = BASS_MIDI_StreamCreate(1, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE, 1);
BASS_ChannelSetAttribute(_bassMidi.stream, BASS_ATTRIB_NOBUFFER, 1)

However, I get a BASS_ERROR_NOTAVAIL error when BASS_ChannelSetAttribute is called.
What have I done wrong ?

Thanks for your help !

Ian @ un4seen

Decoding channels (with BASS_STREAM_DECODE set) don't have a playback buffer, so the BASS_ATTRIB_NOBUFFER option doesn't apply and isn't required.

mdaskal

#1466
Thanks a lot Ian !

I have another question.
I want to copy the sample data from the BASS decoding channel to my Audio Unit output.
Here is my code :
float* data = new float[frameCount];
QWORD length = BASS_ChannelGetData(_bassMidi.stream, data, DWORD(frameCount) | BASS_DATA_FLOAT);

for (int channel = 0; channel < chanCount; ++channel) {
    // Get pointer to mutable output buffer
    float* out = (float*)outBufferListPtr->mBuffers[channel].mData;
   
    for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
        const int frameOffset = int(frameIndex + bufferOffset);
        out[frameOffset] = data[frameIndex];
    }
}

It doesn't seem to work, as I hear click noises instead of the midi sequence it is supposed to play...
What am I missing here ?

Thanks !

Ian @ un4seen

BASS_ChannelGetData "length" parameter is in bytes, so you need to multiply by 4 (the size of a "float") in that call. It looks like you should also multiply both that and the "data" array by "chanCount". So this:

float* data = new float[frameCount * chanCount];
DWORD length = BASS_ChannelGetData(_bassMidi.stream, data, frameCount * chanCount * sizeof(float));

It won't do any harm, but there's no need to include the BASS_DATA_FLOAT flag if the channel is already floating-point (has BASS_SAMPLE_FLOAT set).

mdaskal

Great thanks Ian !!
I implemented what you suggested.

Unfortunately the decoded sample data (retrieved with BASS_ChannelGetData) are all equal to zero.

Here is my initialization sequence :

BASS_Init(-1, 44100, 0, 0, NULL);
stream = BASS_MIDI_StreamCreate(1, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE, 1);
BASS_ChannelSetAttribute(_bassMidi.stream, BASS_ATTRIB_NOBUFFER, 1)
....
Then a Midi sequence is played by the Sequencer and MIDI events are forwarded to BASS using BASS_MIDI_StreamEvents(...)

...
Finally, in the audio Callback of my Audio Unit I read the decoded sample data as explained previously :
float* data = new float[frameCount * chanCount];
DWORD length = BASS_ChannelGetData(_bassMidi.stream, data, frameCount * chanCount * sizeof(float));

Do you see any reason why there is no output?

Thanks again !

Ian @ un4seen

It could be that there's no soundfont loaded to provide the instrument sounds. Have you set one via either BASS_MIDI_StreamSetFonts or the BASS_CONFIG_MIDI_DEFFONT option? If you don't have a soundfont, a couple can be found on the BASS webpage (next to the BASSMIDI download).

mdaskal

Hi Ian,

Yes I forgot to mention that I first loaded a soundfont before sending midi events :
       
HSOUNDFONT newfont = BASS_MIDI_FontInit(fontPath.c_str(), 0);
if (newfont) {
  BASS_MIDI_FONT soundfont;
  soundfont.font = newfont;
  soundfont.preset = 0;
  soundfont.bank = 0;
  BASS_MIDI_StreamSetFonts(_bassMidi.stream, &soundfont, 1)
}

Ian @ un4seen

Try setting the BASS_MIDI_FONT "preset" value to -1 (to use the soundfont for all presets). If there's still no sound, also confirm that the BASS_MIDI_StreamSetFonts call is successful, ie. returning true.

If you will always be using a single soundfont then you could try using the BASS_CONFIG_MIDI_DEFFONT option instead of BASS_MIDI_FontInit and BASS_MIDI_StreamSetFonts:

BASS_SetConfigPtr(BASS_CONFIG_MIDI_DEFFONT, fontPath.c_str());

Fischert

I assume the bass-implementation in iOS is embedded into the AVFoundation Framework.

So is it possible to use other e.g. Apple-AudioUnits together with the Bass-Library?

Best regards
Thomas

Ian @ un4seen

Quote from: FischertI assume the bass-implementation in iOS is embedded into the AVFoundation Framework.

I'm not entirely sure what you mean by that. BASS does use the AVFoundation framework but I wouldn't say it's embedded.

Quote from: FischertSo is it possible to use other e.g. Apple-AudioUnits together with the Bass-Library?

BASS doesn't include built-in support for using AudioUnits. I think it's still possible to use them but it would need to be implemented by the user (you). I've never tried that myself, so I'm afraid I'm unable to advise on the specifics.

mdaskal

Quote from: FischertI assume the bass-implementation in iOS is embedded into the AVFoundation Framework.

So is it possible to use other e.g. Apple-AudioUnits together with the Bass-Library?

Best regards
Thomas

Hi Thomas,
We are currently trying to integrate the BASSMIDI library into an iOS AudioUnit.
It's not fully working yet but it's sound like it will be working fine at the end.

The basic idea is to :
1- Forward the MIDI events received in input of the AudioUnit (handleMIDIEvent() method) to the BASSMIDI library
2- Copy the output of the BASSMIDI decoding channel to the AudioUnit's output (in process(AUAudioFrameCount frameCount, AUAudioFrameCount bufferOffset))
For this last step you have to make the BASSMIDI stream a "decoding channel" by setting the BASS_STREAM_DECODE flag on it. That will allow you to generate the output as needed with BASS_ChannelGetData (instead of BASS_ChannelPlay), which you can then copy to the output buffer.

Hope that it helps !

Fischert

Hi mdaskal,

That sounds very interesting! Pls. keep me informed!!

Best regards
Thomas

mdaskal

Quote from: FischertHi mdaskal,

That sounds very interesting! Pls. keep me informed!!

Best regards
Thomas

Hi Thomas,
We could finalize the integration of the BASSMIDI library into an AUv3, and it works perfectly well!
Best wishes
 

Fischert

Hi mdaskal,

Congratulations!!

Is it possible to get that AUv3?

Best regards
Thomas

Dorian

Can't access the sample app and I can't seem to #import or #include the bass.h file into an iOS objective c code.


Quote from: DrummerBOkay, here is a sample app, demonstrating how to make BASS play back music in the background, and control playback with the multitask bar controls. Actually the app can also be remote controlled with some 3rd party iPhone accessories and speakers.

http://cl.ly/4513342M223M3v0s2Y3T

ECSalute

Additional setup steps (may be useful for other people)
> Drag bass.h into your project
> OPTIONAL : create a Header.h file and #include bass.h
> Link your header file with your project (Objective C bridging Header)
> Build
> OPTIONAL : Abilitate "Allow Arbitrary Loads" in "App transport security settings"

With this bass works with my project