|
amplitude89
Posts: 8
|
 |
« Reply #340 on: 14 Dec '11 - 07:21 » |
Quote
|
I am writing music education software on the iPad, and my approach has been to use BASSMIDI to play midi events in real time. It would be ideal if I could have an objective C wrapper to an array of BASS_MIDI_EVENT structures, and then send this array into BASS to be played. But BASS_MIDI_StreamEvents method ignores the tic member of the BASS_MIDI_EVENT struct, i.e. it doesn't recognize the time of a midi event, it just does it immediately. This means that iOS has to handle the timing of events, which it is not set up well to do. Currently I am just doing,
[self noteOn:stream]; //send note off message to BASS [NSThread sleepForTimeInterval:self.duration]; [self noteOff:stream]; //send note off message to BASS
However, the variability in timing/synchronization for relying on NSThread (or NSTimer, etc.) to give accurate timing for notes is unacceptable.
The other way to do this is to just have BASS play a midi file that I have generated myself. If so, is there a way to convert an array of BASS_MIDI_EVENT structs to an actual midi file, something that BASS_MIDI_StreamCreateFile can use? Although ideally, I don't want to actually save all this files on iPad itself...Any suggestions? This seems like a significant flaw.
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15259
|
 |
« Reply #341 on: 14 Dec '11 - 16:51 » |
Quote
|
Interestingly enough, changing that notification to send after 1024 KB seems to be making all the AAC files work! So you are correct that they seem to need about 600KB to identify...
The amount needed will vary from file to file, eg. some will have more and/or larger headers/atoms to get through than others. But your solution of simply retrying after downloading more seems like it should work well enough  I am writing music education software on the iPad, and my approach has been to use BASSMIDI to play midi events in real time. It would be ideal if I could have an objective C wrapper to an array of BASS_MIDI_EVENT structures, and then send this array into BASS to be played. But BASS_MIDI_StreamEvents method ignores the tic member of the BASS_MIDI_EVENT struct, i.e. it doesn't recognize the time of a midi event, it just does it immediately. This means that iOS has to handle the timing of events, which it is not set up well to do. Currently I am just doing,
[self noteOn:stream]; //send note off message to BASS [NSThread sleepForTimeInterval:self.duration]; [self noteOff:stream]; //send note off message to BASS
However, the variability in timing/synchronization for relying on NSThread (or NSTimer, etc.) to give accurate timing for notes is unacceptable.
The other way to do this is to just have BASS play a midi file that I have generated myself. If so, is there a way to convert an array of BASS_MIDI_EVENT structs to an actual midi file, something that BASS_MIDI_StreamCreateFile can use? Although ideally, I don't want to actually save all this files on iPad itself...Any suggestions? This seems like a significant flaw.
Yes, unfortunately, BASS_MIDI_StreamEvent(s) doesn't currently include timing control. The timing granularity of live events is determined by the update period, so one thing you can do to improve matters is to lower that via the BASS_CONFIG_UPDATEPERIOD setting (with BASS_SetConfig). You may want to lower the BASS_CONFIG_BUFFER setting too, to reduce the latency. You can find a demonstration of using these options in the SYNTH example included in the BASSMIDI package on OSX. If minimum latency is required, another option is to disable the buffering system on the MIDI stream via the BASS_ATTRIB_NOBUFFER option (with BASS_ChannelSetAttribute). You can find a demonstration of that in the SYNTH example included in the BASS package on OSX. Also see the documentation for details on this option (and the others mentioned). If you have a sequence of events that you want to play, then another option may be to use "mixtime" BASS_SYNC_POS syncs, ie. set a sync on the MIDI stream (via BASS_ChannelSetSync) at the position that you want an event to be applied and then apply the event in the SYNCPROC function. That will give perfect timing, ie. the events will be heard exactly at the wanted positions.
|
|
|
|
|
Logged
|
|
|
|
|
amplitude89
Posts: 8
|
 |
« Reply #342 on: 18 Dec '11 - 06:08 » |
Quote
|
Ok, I'm going to have my code create mid files, and have BASS_MIDI_StreamCreateFile read them in. However I can't get the function call to work...any suggetsions besides:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Chopin Ocean Etude" ofType:@"mid"]; NSData *myData = [NSData dataWithContentsOfFile:filePath];
HSTREAM stream=BASS_MIDI_StreamCreateFile(FALSE, [myData bytes], 0, 0, 0, 44100);
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15259
|
 |
« Reply #343 on: 19 Dec '11 - 17:26 » |
Quote
|
I think this should do it... NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Chopin Ocean Etude" ofType:@"mid"]; HSTREAM stream=BASS_MIDI_StreamCreateFile(FALSE, [filePath UTF8String], 0, 0, 0, 44100);
|
|
|
|
|
Logged
|
|
|
|
|
amplitude89
Posts: 8
|
 |
« Reply #344 on: 20 Dec '11 - 05:30 » |
Quote
|
Thanks! I had tried that, but without the [filePath UTF8String] part. Now it works!
|
|
|
|
|
Logged
|
|
|
|
|
SimonH
Posts: 7
|
 |
« Reply #345 on: 11 Jan '12 - 21:07 » |
Quote
|
That's strange, it should resume after an interruption. I will send you a debug version to find out what is happening.
I know this is an old thread but... How does one configure an iOS app to 'duck' it's own audio when sent to the background and conversely, how does one configure an iOS app to 'duck' all other audio when it comes to the foreground? I'm having the same problem, and I have the latest libraries from the top of this thread. When my app is interrupted by a phone call the audio never resumes, even if I try and reinitialise via BASS_Init and play. I have been puzzling over this for a few days now, any ideas are very welcome?
|
|
|
|
« Last Edit: 11 Jan '12 - 21:16 by SimonH »
|
Logged
|
|
|
|
|
HyperNovaSoftware
Posts: 46
|
 |
« Reply #346 on: 11 Jan '12 - 21:25 » |
Quote
|
I'm having the same problem, and I have the latest libraries from the top of this thread.
When my app is interrupted by a phone call the audio never resumes, even if I try and reinitialise via BASS_Init and play. I have been puzzling over this for a few days now, any ideas are very welcome?
Here is how I got it working on an iPad. Not sure if it works on an iPhone. -(void)setTheSessionActiveWithMixing:(BOOL)shouldDuck otherAppsShouldDuck:(BOOL)otherAppsShouldDuck { UInt32 value = NO; AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(value), &value); UInt32 isOtherAudioPlaying = 0; UInt32 size = sizeof(isOtherAudioPlaying); AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &size, &isOtherAudioPlaying); if (isOtherAudioPlaying && otherAppsShouldDuck) AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(value), &value); }
-(void)applicationDidBecomeActive:(UIApplication *)application { BASS_Start(); [self setTheSessionActiveWithMixing:NO otherAppsShouldDuck:YES]; AudioSessionSetActive(YES); // // Set the application volume to the current app Volume Level. // BASS_SetConfig(BASS_CONFIG_GVOL_STREAM,(int)(10000.00f * appVolumeLevel)));
-(void)applicationWillTerminate:(UIApplication *)application { BASS_ChannelSlideAttribute((DWORD)channel.stream, BASS_ATTRIB_VOL, -1, 50000); // // Fade the application volume out. // BASS_SetConfig(BASS_CONFIG_GVOL_STREAM,0)); }
|
|
|
|
|
Logged
|
|
|
|
|
AnthonyM
Posts: 47
|
 |
« Reply #347 on: 11 Jan '12 - 23:52 » |
Quote
|
To start off with I would like to say that the BASS library and the iOS port of it are both great. Secondly, maybe a separate forum category for "BASS for iOS" would be good so that we can ask questions related to it without making this thread huge. Onto my question: Is there any way I can get music from the "iPod Library" and get it into a BASS Stream? Thanks 
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15259
|
 |
« Reply #348 on: 12 Jan '12 - 18:05 » |
Quote
|
Secondly, maybe a separate forum category for "BASS for iOS" would be good so that we can ask questions related to it without making this thread huge.
I'm not sure a separate forum category would be a good idea. Most things in BASS are the same on all supported platforms, so a question from an iOS user could also be relevant to users of other platforms, but other users with the same question might not find the answer if it's hidden away in an iOS-specific forum  This thread does seem to have become a place for all iOS-related stuff, but it is also fine for people to start their own threads for their iOS-related questions. Is there any way I can get music from the "iPod Library" and get it into a BASS Stream?
I haven't looked into this recently, but as far as I know, it isn't possible for apps to access files in the iPod Library directly. But files can be copied into the app's sandbox (via AVAssetExportSession) and then accessed from there, eg. used in BASS_StreamCreateFile calls. Here's a class that can be used to simplify the file copying process... https://bitbucket.org/artgillespie/tslibraryimport
|
|
|
|
|
Logged
|
|
|
|
|
SimonH
Posts: 7
|
 |
« Reply #349 on: 12 Jan '12 - 19:54 » |
Quote
|
@fattymcbutterpants - thanks a lot that worked for me, also on iPhone
|
|
|
|
|
Logged
|
|
|
|
|
AnthonyM
Posts: 47
|
 |
« Reply #350 on: 13 Jan '12 - 04:24 » |
Quote
|
@Ian - Thanks, I ended up using basically the same method, works like a charm and copies the file in approx 1 second or less.
|
|
|
|
|
Logged
|
|
|
|
|
AnthonyM
Posts: 47
|
 |
« Reply #351 on: 14 Jan '12 - 08:53 » |
Quote
|
I'm currently doing the following: BASS_ChannelSetSync(deckHandle, BASS_SYNC_END, 0, &EndSyncCallback, self);
void CALLBACK EndSyncCallback(HSYNC handle, DWORD channel, DWORD data, void *user) { DeckViewController *me = (DeckViewController*)user; // Insert other code that uses 'self'/me here }
This code is within the DeckViewController class. I am doing this because I can't access any of the classes functions from within the callback. Is there a better way of doing this? Thanks 
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15259
|
 |
« Reply #352 on: 17 Jan '12 - 14:21 » |
Quote
|
That is the correct/best way to do it as far as I'm aware, but I'm no Objective-C expert 
|
|
|
|
|
Logged
|
|
|
|
|
sui
Guest
|
 |
« Reply #353 on: 20 Jan '12 - 07:45 » |
Quote
|
Hello ! I have a problem, I hope someone can help me. I want to stream an AAC using BASS, but I don't know how to do it. I understood I must use BASS_StreamCreateFileUser and BASS_StreamPutFileData, but I don't know how to write callbacks (I'm really a newbie). Here is my code : - (void) prepare { int error; BASS_Init(-1, 44100, 0, 0, NULL); error = BASS_ErrorGetCode(); NSURLRequest *request = [NSURLRequest requestWithURL:@"myURL"]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start]; }
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { data = [[NSMutableData data] retain]; BASS_FILEPROCS fileprocs={MyFileCloseProc, MyFileLenProc, MyFileReadProc, MyFileSeekProc}; stream = BASS_StreamCreateFileUser(STREAMFILE_BUFFERPUSH, 0, &fileprocs, data); int error = BASS_ErrorGetCode(); DLog(@"error %d", error); // Stream is null, I don't know why BASS_ChannelPlay(stream, NO); error = BASS_ErrorGetCode(); }
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)new_data { [data appendData:new_data]; BASS_StreamPutFileData(stream1, [new_data bytes],new_data.length); int error = BASS_ErrorGetCode(); DLog(@"error %d", error); }
void CALLBACK MyFileCloseProc(void *user) { fclose(user); // close the file }
QWORD CALLBACK MyFileLenProc(void *user) { NSMutableData *data = (NSMutableData *)user; return [data length]; }
DWORD CALLBACK MyFileReadProc(void *buffer, DWORD length, void *user) { return fread(buffer, 1, length, user); // I think it does not work with NSMutableData }
BOOL CALLBACK MyFileSeekProc(QWORD offset, void *user) { return !fseek(user, offset, SEEK_SET); // seek to offset }
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15259
|
 |
« Reply #354 on: 20 Jan '12 - 17:12 » |
Quote
|
Streaming AAC from the internet on iOS is pretty complicated. Probably not the best choice for a 1st project  The problem is that the buffered file system isn't supported when using a CoreAudio codec (eg. for AAC); if it was supported, you could simply use BASS_StreamCreateURL and not bother with BASS_StreamCreateFileUser. That means you can't use STREAMFILE_BUFFERPUSH in your BASS_StreamCreateFileUser call; FILESYSTEM_NOBUFFER (the unbuffered file system) is the only option available when playing AAC. That introduces another problem in that it expects the data to be available immediately and any delays (eg. waiting for data to download) will block the decoding thread, possibly resulting in breaks in the output, but that can be mitigated by having a dedicated thread hosting the stream decoding. Here's a previous thread on the subject... www.un4seen.com/forum/?topic=13185
|
|
|
|
|
Logged
|
|
|
|
|
arlomedia
Posts: 9
|
 |
« Reply #355 on: 21 Jan '12 - 21:11 » |
Quote
|
I'm using BASS for real-time effects processing in two different apps. I've heard from a few users saying they don't hear any sound on the iPhone 4s. Is there any known incompatibility between the current BASS for iOS and the 4s hardware?
I don't have a 4s to test with, but I'll borrow one this week.
|
|
|
|
|
Logged
|
|
|
|
|
einsteinx2
Posts: 61
|
 |
« Reply #356 on: 22 Jan '12 - 20:32 » |
Quote
|
I'm using BASS for real-time effects processing in two different apps. I've heard from a few users saying they don't hear any sound on the iPhone 4s. Is there any known incompatibility between the current BASS for iOS and the 4s hardware?
I don't have a 4s to test with, but I'll borrow one this week.
I'm using a 4S and I haven't had any issues with BASS not playing any sound on my device, though maybe you're using some BASS function I'm not.
|
|
|
|
|
Logged
|
|
|
|
|
einsteinx2
Posts: 61
|
 |
« Reply #357 on: 22 Jan '12 - 20:40 » |
Quote
|
@Ian, I'm am having an issue properly down/upsampling and audio stream. I had posted a little while back about some sound quality issues I was having with BASS compared to Audio Queue Services. Mainly volume being much lower and not as "thick" in the mid/low end. I'm not sure what framework you're using internally in BASS for audio playback, but I was able to fix my sound quality issues by using BASS only for decoding and passing sample data to an audio queue. (maybe you could incorporate that internally at some point?)
The issue I have is that only files with the same sample rate as the audio queue play properly. If I have say a 96KHz file and try to play that in a 44.1KHz queue, it plays very slowly, and a 22.05KHz file plays double speed. Obviously because there are more or less samples than expected.
I'm having trouble getting BASS to change the sample rate. I've tried a few different things and none have worked. I assumed if I create a BASSMix stream in DECODE mode and set it's sample rate to the same as the audio queue, it should down/upsample for me. When I do this, the files play at the correct speed but sound very bad (hard to explain the sound, like loud clicking I guess). I've tried using the declick option and that didn't work.
Is there a proper way I should be doing this? I saw somewhere in the forums a function to manually change sample rate, but I'd rather use a built in BASS function if possible. When I was previously using BASS to output my audio, it was dealing with sample rates just fine (except for files over 96KHz then there was loud whitenoise, which I sent you a test file for) so it obviously has the capability to resample audio streams, I just haven't figured out how to get that resampling to happen when just decoding.
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15259
|
 |
« Reply #358 on: 23 Jan '12 - 17:21 » |
Quote
|
I'm using BASS for real-time effects processing in two different apps. I've heard from a few users saying they don't hear any sound on the iPhone 4s. Is there any known incompatibility between the current BASS for iOS and the 4s hardware?
I don't have a 4s to test with, but I'll borrow one this week.
Is BASS handling the device input/output as well as applying effects, or is that handled in some other way? If the latter, it might be that something has changed in that stuff, eg. perhaps the sample format has changed? @Ian, I'm am having an issue properly down/upsampling and audio stream. I had posted a little while back about some sound quality issues I was having with BASS compared to Audio Queue Services. Mainly volume being much lower and not as "thick" in the mid/low end. I'm not sure what framework you're using internally in BASS for audio playback, but I was able to fix my sound quality issues by using BASS only for decoding and passing sample data to an audio queue. (maybe you could incorporate that internally at some point?)
The sound quality problem with the 192KHz test file that you uploaded previously is caused by the resampling. For performance reasons, BASS uses linear interpolation when resampling on iOS, which doesn't give the greatest quality. I'm looking into adding a higher quality option for when quality is more important than performance. The issue I have is that only files with the same sample rate as the audio queue play properly. If I have say a 96KHz file and try to play that in a 44.1KHz queue, it plays very slowly, and a 22.05KHz file plays double speed. Obviously because there are more or less samples than expected.
I'm having trouble getting BASS to change the sample rate. I've tried a few different things and none have worked. I assumed if I create a BASSMix stream in DECODE mode and set it's sample rate to the same as the audio queue, it should down/upsample for me. When I do this, the files play at the correct speed but sound very bad (hard to explain the sound, like loud clicking I guess). I've tried using the declick option and that didn't work.
You're on the right track with BASSmix; it will resample "decoding channels". Like BASS, it currently uses linear interpolation on iOS, but it also has an extra filter option (BASS_MIXER_FILTER) that should help. Regarding the clicking problem, please post your code to see if there is anything in that to cause it. You could also try going back to letting BASS handle the output, but have BASSmix do the resampling (with the filter enabled). That could look something like this... BASS_INFO info; BASS_GetInfo(&info); // get output device info mixer=BASS_Mixer_StreamCreate(info.freq, 2, BASS_MIXER_END); // create a mixer with same sample rate decoder=BASS_StreamCreateFile(FALSE, filename, 0, 0, BASS_STREAM_DECODE); // create a "decoding channel" for the file to play BASS_Mixer_StreamAddChannel(mixer, decoder, BASS_MIXER_FILTER); // add it to the mixer with extra filtering enabled BASS_ChannelPlay(mixer, FALSE); // start the mixer
Please see the documentation for details on the aforementioned functions.
|
|
|
|
|
Logged
|
|
|
|
|
skinnyTod
Posts: 22
|
 |
« Reply #359 on: 23 Jan '12 - 20:16 » |
Quote
|
-
|
|
|
|
« Last Edit: 26 Jan '12 - 10:29 by skinnyTod »
|
Logged
|
|
|
|
|