BASS for iOS (iPhone/iPad)

Started by Ian @ un4seen,

Ian @ un4seen

Quote from: Gurt87Guys, how can i get effect like "Concert hall", "Subway", "Bar", "Sidewalk", etc.   with BASS library?

Preset environments like that are not currently available. You can emulate some of them via the BASS_FX_DX8_REVERB parameters, but probably not all. It may be possible to emulate more environments by adding more effects to it.

Quote from: SerginhoI've tried to user BASS_FX with different params, but with no results. Any help?

      hfxHandle = BASS_ChannelSetFX(chan, BASS_FX_DX8_FLANGER, 1);
      BASS_DX8_FLANGER bigAreaParams = { 500.0, 36.0, -15.0, 15.0f, 115, 15.0f, 115};
      BASS_FXSetParameters(hfxHandle, &bigAreaParams);

Is the BASS_FXSetParameters call reporting success, ie. returning TRUE? I suspect it's failing as some of the parameters appear to be out of range. Please see the BASS_DX8_FLANGER documentation for the valid ranges.

Gurt87

BASS_FXSetParameters returns FALSE each time. We've notices changes only while changing
BASS_ChannelSetFX(chan, BASS_FX_BFX_DAMP, 1);
if we changes params


float fTarget = 0.98f;
float fQuiet = 0.04f;
float fRate = 0.02f;
float fGain = 2.0f;
float fDelay = 0.2f;


hfxHandle = BASS_ChannelSetFX(chan, BASS_FX_BFX_DAMP, 0);
     BASS_BFX_DAMP damp = {fTarget, fQuiet, fRate, fGain, fDelay, chan};
                          BOOL result = BASS_FXSetParameters(hfxHandle, &damp);
we always receive FALSE  


Ian @ un4seen

Please check the error code, using BASS_ErrorGetCode.

Also, is the BASS_ChannelSetFX call successful, ie. is "hfxHandle" non-0? If it is 0, then it suggests that the BASS_FX add-on has not been loaded. Have you added it (LIBBASS_FX.A) to your project's "Link Binary With Libraries" branch?

Also note that the BASS_BFX_DAMP "lChannel" parameter is not a BASS channel handle (eg. "chan"), but rather it determines which audio channels (eg. left/right) the effect should apply to. You can use BASS_BFX_CHANALL to have it apply to all. Please see the BASS_FX documentation for details.

Gurt87

When im use BASS_FX_DX8_REVERB everything is OK. Error code = 0, hfxHandle != 0;
HSTREAM chan;   //typedef DWORD HSTREAM; // sample stream handle
HFX hfxHandle;   //typedef DWORD HFX; // DX8 effect handle

//-----------

hfxHandle = BASS_ChannelSetFX(chan, BASS_FX_DX8_REVERB, 1);
BASS_DX8_REVERB fx;
fx.fInGain = 0;
fx.fReverbMix = 0;
fx.fReverbTime = 100;
fx.fHighFreqRTRatio = 0.001;
BOOL result = BASS_FXSetParameters(hfxHandle, &fx);

//result == TRUE

When im try use BASS_FX_BFX_DAMP, Error code = 19, hfxHandle == 0;

LIBBASS_FX.A in project.
hfxHandle = BASS_ChannelSetFX(chan, BASS_FX_BFX_DAMP, 1);
BASS_BFX_DAMP fx;
fx.fTarget = 0.5;
fx.fQuiet = 0.5;
fx.fRate = 0.5;
fx.fGain = 0;
fx.fDelay = 0.5;
fx.lChannel = BASS_BFX_CHANALL;
BOOL result = BASS_FXSetParameters(hfxHandle, &fx);

//result == FALSE every time

LIBBASS_FX.A in project.

Ian @ un4seen

Error code 19 is BASS_ERROR_ILLTYPE, which means that the "type" parameter (BASS_FX_BFX_DAMP) was not recognised. That would indicate that BASS_FX is not loaded. You may need to add a BASS_FX function call (eg. BASS_FX_GetVersion) to your app to get it linked into your app. If it still doesn't work, do you see any errors in the XCode build log?

Gurt87

When im try call BASS_FX_GetVersion(); im get in my debug log
Undefined symbols:
  "operator delete[](void*)", referenced from:
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
  "operator delete(void*)", referenced from:
      _BASS_FX_BPM_Free in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_Free in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_CallbackSet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_ReverseGetSource in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_ReverseGetSource in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      __textcoal_nt@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __textcoal_nt@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __textcoal_nt@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
  "operator new[](unsigned long)", referenced from:
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
  "operator new(unsigned long)", referenced from:
      _BASS_FX_BPM_CallbackSet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_ReverseGetSource in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_ReverseGetSource in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_BPM_BeatDecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
      _BASS_FX_TempoCreate in libbass_fx.a(libbass_fx.a-i386-master.o)
  "___cxa_pure_virtual", referenced from:
      __const@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
      __const_coal@0 in libbass_fx.a(libbass_fx.a-i386-master.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status

.......



Its mean that FX not working???
But how BASS_FXSetParameters(hfxHandle, &fx)   returns TRUE ??
BASS_FXSetParameters - its function BASS_FX?

vitalic

Hello guys,

I'm finally confused with bass_fx. I've read that latest working copy of bass_fx witch works with ios4 is beta now.
From my own experience, I was unable to add official version libbassfx.a to project, beta works but partially.
Could you please help me with working files and piece of code with bass_fx usage.

I'll be much appreciate your help!
Thanks!

Vitaliy

Ian @ un4seen

Quote from: Gurt87When im try call BASS_FX_GetVersion(); im get in my debug log
Undefined symbols:
  "operator delete[](void*)", referenced from:
      _BASS_FX_BPM_DecodeGet in libbass_fx.a(libbass_fx.a-i386-master.o)
...

Adding "-lstdc++" to your project's "Other Linker Flags" setting should sort that (BASS_FX requires the C++ library).

Quote from: Gurt87But how BASS_FXSetParameters(hfxHandle, &fx)   returns TRUE ??
BASS_FXSetParameters - its function BASS_FX?

BASS_FXSetParameters is a BASS function, as is BASS_ChannelSetFX. The BASS_FX add-on adds support for more effects to those functions.

Gurt87

#158
QuoteAdding "-lstdc++" to your project's "Other Linker Flags" setting should sort that (BASS_FX requires the C++ library).
Thanks! it works!

Now i have another question: how can i get "dump" effect?
if im use BASS_FX_BFX_DUMP i not hear any changes...BASS_FXSetParameters returns TRUE;

Maybe i set bad parameters?

      BASS_BFX_DAMP fx;
      fx.fTarget = 0.98f;
      fx.fQuiet = 0.04f;
      fx.fRate = 0.02f;
      fx.fGain = 2.0f;
      fx.fDelay = 0.2f;
      fx.lChannel = BASS_BFX_CHANALL
 

Ian @ un4seen

The effect of the "DAMP" effect may not be very noticeable. It raises/lowers the level towards a target level (fTarget), but if the sample data is already at/around that level, then it doesn't have much to do :)

Gurt87

But how can i get sound like piano dump (deaf, short  sound).
what fx effect i must use??

(Sorry for my English..)

Ian @ un4seen

The "DAMP" in "BASS_FX_BFX_DAMP" is short for "Dynamic Amplification". Perhaps you're looking for a dampening/softening effect instead? If so, you could try a low-pass filter, eg. BASS_FX_BFX_LPF.

Johny Maker

Hi, there.
I'd like to use output sound recording (not from mic, but all sounds in my application).

I managed to record sound from mic like this:

  BASS_RecordInit(rchan);
    BASS_RecordSetDevice(rchan);
    BASS_RecordSetInput(rchan, BASS_INPUT_ON, 0.3f);
// allocate initial buffer and make space for WAVE header
recbuf=malloc(BUFSTEP);
reclen=44;
// fill the WAVE header
memcpy(recbuf,"RIFF\0\0\0\0WAVEfmt \20\0\0\0",20);
memcpy(recbuf+36,"data\0\0\0\0",8);
wf=(WAVEFORMATEX*)(recbuf+20);
wf->wFormatTag=le_16(1);
wf->nChannels=le_16(2);
wf->wBitsPerSample=le_16(16);
wf->nSamplesPerSec=le_32(44100);
wf->nBlockAlign=le_16(4);
wf->nAvgBytesPerSec=le_32(176400);
// start recording @ 44100hz 16-bit stereo
           
    if (rchan=BASS_RecordStart(44100,2,0,&RecordingCallback,0)) {
        NSLog(@"Recording start");
    } else {
        NSLog(@"Recording falied");
    }

How can I do output sound recording?

Thanks.

Ian @ un4seen

I'm not sure iOS includes something like a "Stereo Mix" or "What U Hear" recording option, so I don't think it will be possible to capture the output via the recording functions.

One way you could do it is to use the BASSmix add-on and play everything via a mixer (eg. using BASS_Mixer_StreamAddChannel), which would allow you to capture the mix via a DSP function set on the mixer, or you could use the BASSenc add-on if you want to write the mix to a file. Having the extra layer of a mixer would normally increase latency due to its playback buffering (see BASS_CONFIG_BUFFER), but it is possible to bypass that buffering via the BASS_ATTRIB_NOBUFFER option.

Peter Andersen

Fantastic news..

Quote from: kenIn there is any C# coders that use MonoTouch framework for developing iPhone apps, I'm happy to tell you that BASS for IPhone works with MonoTouch (yes you can link static libraries in MonoTouch). I can make a simple MonoTouch example if needed.

/Ken

Gurt87

Why function BASS_RecordSetInput always return FALSE??
Maybe mistake in parameters?

BASS_RecordSetInput(BASS_INPUT_TYPE_MIC, BASS_INPUT_ON, 1f);

if I use BASS_INPUT_TYPE_LINE i get record from LINE OUT?

Thanks




Ian @ un4seen

That "input" parameter is invalid (it should be an input number rather than a BASS_INPUT_TYPE_xxx constant), but the BASS_RecordSetInput function is not currently supported on the iOS platform anyway, so it doesn't really matter what parameters you use :)

What input are you wanting to record from?

Johny Maker

Quote from: Ian @ un4seenI'm not sure iOS includes something like a "Stereo Mix" or "What U Hear" recording option, so I don't think it will be possible to capture the output via the recording functions.

One way you could do it is to use the BASSmix add-on and play everything via a mixer (eg. using BASS_Mixer_StreamAddChannel), which would allow you to capture the mix via a DSP function set on the mixer, or you could use the BASSenc add-on if you want to write the mix to a file. Having the extra layer of a mixer would normally increase latency due to its playback buffering (see BASS_CONFIG_BUFFER), but it is possible to bypass that buffering via the BASS_ATTRIB_NOBUFFER option.

Thanks in advance!
Works great!

One more feature I wanna ask you:
I managed to save my mixed stream as:
NSString *fileName = [DOCUMENTS_FOLDER stringByAppendingFormat:@"/%@.caf", file];

    BASS_Encode_StartCAFile(mixer, 'caff', 'ima4', 0, 0, [fileName cStringUsingEncoding:NSUTF8StringEncoding]);
    BASS_ChannelPlay(mixer, 0); // start the channel playing & encoding

This works.

But I've tried a lot to save it in m4a or mp4 format with no luck:
BASS_Encode_StartCAFile(mixer, 'm4af', 'alac', 0, 0, "output.m4a");
BASS_ErrorGetCode(); // returns 0
BASS_ChannelPlay(mixer, 0); // start the channel playing & encoding
File is created, but with no luck to play it, it's lenght is only 26 bytes. Where is my mistake?

P.S.
iOS 4.3.2
Mixer is:
mixer = BASS_Mixer_StreamCreate(44100, 2, BASS_SAMPLE_FLOAT);
Thanks!

Ian @ un4seen

I don't think the ALAC codec supports floating-point, so it's a bit surprising that it even accepted the mixer's format. Anyway, to fix the empty file problem, you could try adding the BASS_ENCODE_FP_16BIT flag to the BASS_Encode_StartCAFile call, to have BASSenc convert the sample data to 16-bit integer before feeding it to the codec.

Johny Maker

Quote from: Ian @ un4seenI don't think the ALAC codec supports floating-point, so it's a bit surprising that it even accepted the mixer's format. Anyway, to fix the empty file problem, you could try adding the BASS_ENCODE_FP_16BIT flag to the BASS_Encode_StartCAFile call, to have BASSenc convert the sample data to 16-bit integer before feeding it to the codec.

Hi, again.
I've tried what you suggest.
    DWORD aChan=BASS_StreamCreateFile(FALSE, [respath cStringUsingEncoding: NSUTF8StringEncoding], 0, 0, BASS_SAMPLE_FLOAT);
    BASS_Encode_StartCAFile(aChan, 'mp4f', 'aac ', BASS_ENCODE_FP_16BIT, 128000, [fileName cStringUsingEncoding:NSUTF8StringEncoding]);
    NSLog(@"Decode error is: %d", BASS_ErrorGetCode()); // Get 0
    BASS_ChannelPlay(aChan, 0); //Hear sound
    NSLog(@"Code is: %d", BASS_ErrorGetCode()); // Get 0

File is created and has (seems to be) right size (2 secs is near 100kb). But I'm unable to play it with any player (ex. QuickTime).
What is a problem?

Also tried to encode mono like this (no luck too):
    DWORD aChan=BASS_StreamCreateFile(FALSE, [respath cStringUsingEncoding: NSUTF8StringEncoding], 0, 0, BASS_SAMPLE_MONO);
    BASS_Encode_StartCAFile(aChan, 'mp4f', 'aac ', BASS_ENCODE_MONO, 128000, [fileName cStringUsingEncoding:NSUTF8StringEncoding]);
    NSLog(@"Decode error is: %d", BASS_ErrorGetCode()); // Get 0
    BASS_ChannelPlay(aChan, 0); //Hear sound
    NSLog(@"Code is: %d", BASS_ErrorGetCode()); // Get 0

Please, any help.

Ian @ un4seen

Check that you are calling BASS_Encode_Stop at the end of the encoding. I have encountered that problem (an unplayable file) if the app was closed without calling BASS_Encode_Stop.


Gurt87

Hi Ian!

I'm try working with BASSMIDI.
Its works great!
My code
....
if (!BASS_Init(-1,44100,BASS_DEVICE_LATENCY,NULL,NULL)) {
NSLog(@"Can't initialize device");
return;
}

DWORD len=BASS_GetConfig(BASS_CONFIG_UPDATEPERIOD); // get update period
BASS_INFO info;
BASS_GetInfo(&info); // retrieve device info
len+=info.minbuf; // add the 'minbuf'
BASS_SetConfig(BASS_CONFIG_BUFFER, len*1.5); // set the buffer length

// create a channel
chan = BASS_MIDI_StreamCreate(1, BASS_MIDI_NOFX, 0);

             const char *file = [[[NSBundle mainBundle] pathForResource:@"Phatt Presets.Sf2" ofType:@""] UTF8String];
             if ((newfont=BASS_MIDI_FontInit(file,0))) {
NSLog(@"Soundfont loaded!");

BASS_MIDI_FONT sf;
sf.font=newfont;
sf.preset = -1; // use all presets
sf.bank=0; // use default bank(s)
BASS_MIDI_StreamSetFonts(0,&sf,1); // set default soundfont
BASS_MIDI_StreamSetFonts(chan,&sf,1); // set for current stream too
             }

BASS_MIDI_StreamEvent(chan, 0, MIDI_EVENT_MASTERVOL, 16383);
BASS_MIDI_StreamEvent(chan, 0, MIDI_EVENT_VOLUME, 127);
BASS_MIDI_StreamEvent(chan, 0, MIDI_EVENT_BANK, 127);
BASS_MIDI_StreamEvent(chan, 0, MIDI_EVENT_PROGRAM, 10);

BASS_MIDI_StreamEvent(chan, 0, MIDI_EVENT_NOTE, MAKEWORD(60, 100));

            BASS_ChannelPlay(chan,FALSE);

SoundFont presets play great.
But some of them do not stop and continue play.

How can i stop them???

Thanks.


Ian @ un4seen

To stop a note, you need another MIDI_EVENT_NOTE event for the same note but with velocity=0 (in the HIBYTE).

BASS_MIDI_StreamEvent(chan, 0, MIDI_EVENT_NOTE, MAKEWORD(60, 0));

Johny Maker

Hi, there.
I'm developing iOS music application using BASS, it works great, but recently I've received user's feedback that on his iPhone:
QuoteSound is way to quiet and this is because it's coming out of the earpiece (what you use to hear phone calls) and not the external speakers. It's impossible for us to test until we get the notes coming out of the correct speakers at a good volume.

I initialize BASS like this:
BASS_Init(-1, 44100, BASS_DEVICE_DEFAULT, NULL, NULL);
As I read -1  is a default output device. On iPad and iPod works good.

Should I set first parameter to 1 to have sound from speakers?

Please, any help.