19 Jun '13 - 10:07 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: 1 ... 15 16 [17] 18 19 ... 37
  Reply  |  Print  
Author Topic: BASS for iOS (iPhone/iPad)  (Read 115558 times)
Sergey M
Guest
« Reply #320 on: 16 Nov '11 - 17:18 »
Reply with quoteQuote

If streaming every sound, I think it would be a big burden on the file system iOS.
Because sometimes a lot of sounds are playing at the same time.
Logged
einsteinx2
Posts: 61


« Reply #321 on: 17 Nov '11 - 07:29 »
Reply with quoteQuote

I'm having some issues retrieving the bitrate of streaming files. I'm not using BASS_StreamCreateURL but rather downloading the files using NSURLConnection and using BASS_StreamCreateFile with 0 for length.

When playing files that have already been downloaded, bitrate is obtainable using:

DWORD len = BASS_ChannelGetLength(chan, BASS_POS_BYTE);
float time=BASS_ChannelBytes2Seconds(chan, len);

However, when the file is being played while it's downloading, I get very weird results. For one, BASS_ChannelGetLength() seems to return the same result as the first time it is called during a stream instead of showing higher values as more of the song is downloaded. So it will determine the correct bitrate the first time I use the above code, but every time after while the song is playing it shows a higher and higher bitrate.

Is there something I'm doing wrong? Can I do something to make ChannelGetLength return increasing values each time it's called? Or do I need to save the bitrate from the first time I use the above code and just use my saved value every other time I need it?

EDIT: actually it looks like I'm getting mostly incorrect values even at the beginning of a stream that is not completely downloaded. The only files I'm getting correct values for are fully downloaded ones. Is it just not possible to get bitrate info from files that are being downloaded? Somehow the Audio Queue Services framework does it so it must be possible somehow.
« Last Edit: 17 Nov '11 - 07:34 by einsteinx2 » Logged
Ian @ un4seen
Administrator
Posts: 15363


« Reply #322 on: 17 Nov '11 - 15:53 »
Reply with quoteQuote

If streaming every sound, I think it would be a big burden on the file system iOS.
Because sometimes a lot of sounds are playing at the same time.

I don't suppose it will make a massive difference whether the data is read from memory or disk on an iOS device (eg. there are no drive heads to move around), but if you would like a file to be played from memory without it being pre-decoded, you can achieve that by reading it to memory and then passing the memory block to BASS_StreamCreateFile (with mem=true). If the sounds are short, it may be best to simply stick with BASS_SampleLoad and have them pre-decoded to memory, as it's unlikely to have a massive impact on memory usage (due to their size) and PCM will require even less CPU to play than IMA4.

When playing files that have already been downloaded, bitrate is obtainable using:

DWORD len = BASS_ChannelGetLength(chan, BASS_POS_BYTE);
float time=BASS_ChannelBytes2Seconds(chan, len);

However, when the file is being played while it's downloading, I get very weird results. For one, BASS_ChannelGetLength() seems to return the same result as the first time it is called during a stream instead of showing higher values as more of the song is downloaded. So it will determine the correct bitrate the first time I use the above code, but every time after while the song is playing it shows a higher and higher bitrate.

The BASS_ChannelGetLength value will only be updated once the decoder reaches the end of the file, when the true length is known. Perhaps you could use BASS_ChannelGetPosition (with BASS_POS_DECODE flag) in your calculation instead? Something like this...

QWORD filepos=BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT); // current file position
QWORD decpos=BASS_ChannelGetPosition(chan, BASS_POS_BYTE|BASS_POS_DECODE); // decoded PCM position
double bitrate=filepos*8/BASS_ChannelBytes2Seconds(chan, decpos);

So long as the decoder goes through the file in a linear fashion (ie. doesn't seek all over the shop), that should work reasonably well. If you want a live/current bitrate (rather than an average for the entire file), you could monitor the file position's rate of progress.
Logged
einsteinx2
Posts: 61


« Reply #323 on: 17 Nov '11 - 17:53 »
Reply with quoteQuote

Thank you that's working beautifully Smiley
Logged
einsteinx2
Posts: 61


« Reply #324 on: 17 Nov '11 - 18:55 »
Reply with quoteQuote

I'm now trying to incorporate the bass_fx.a library, but am unable to compile. Getting a lot of undefined symbols for architecture armv6 and armv7. Interestingly when I add it to a small sample project that was posted earlier in this thread, it builds without any issues.

EDIT: Turns out I needed to add "-lstdc++" to Other Linker Flags. Now it builds fine. You should mention that in the first post in case others run into the same issue.
« Last Edit: 18 Nov '11 - 00:57 by einsteinx2 » Logged
Sergey M
Guest
« Reply #325 on: 18 Nov '11 - 07:31 »
Reply with quoteQuote

but if you would like a file to be played from memory without it being pre-decoded, you can achieve that by reading it to memory and then passing the memory block to BASS_StreamCreateFile (with mem=true).

Ian, thank  you for the clarification.

Logged
Ian @ un4seen
Administrator
Posts: 15363


« Reply #326 on: 18 Nov '11 - 15:21 »
Reply with quoteQuote

EDIT: Turns out I needed to add "-lstdc++" to Other Linker Flags. Now it builds fine. You should mention that in the first post in case others run into the same issue.

That is actually mentioned in the BASS_FX docs/changelog, but you're right, it could/should also be mentioned in the first post here. So now it is Smiley
Logged
einsteinx2
Posts: 61


« Reply #327 on: 18 Nov '11 - 19:01 »
Reply with quoteQuote

That is actually mentioned in the BASS_FX docs/changelog

Yep, that's how I found it Smiley
Logged
HyperNovaSoftware
Posts: 46


« Reply #328 on: 22 Nov '11 - 19:07 »
Reply with quoteQuote

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?
Logged
polyvision
Posts: 5


« Reply #329 on: 23 Nov '11 - 18:26 »
Reply with quoteQuote

Hi there,

I'm wondering which way you guys use to get music from the ipod-libary ? Are you using the AVAssetExportSession way or BASS_StreamCreateURL via MPMediaItem ?
Logged
jnyang
Guest
« Reply #330 on: 26 Nov '11 - 12:54 »
Reply with quoteQuote

I'm wondering which way you guys use to get music from the ipod-libary ? Are you using the AVAssetExportSession way or BASS_StreamCreateURL via MPMediaItem ?

BASS_StreamCreateURL does not work for MPMediaItem, because only way via AVAsset is allowed to get sound data directly from MPMediaItem URL. For that reason, I am using AVAssetExportSession to export data file to temporary folder and open that file via BASS_StreamCreateFile.

Is there anyone who knows better solution to get music from iPod library?
Logged
amplitude89
Posts: 8


« Reply #331 on: 10 Dec '11 - 08:03 »
Reply with quoteQuote

Just upgraded to XCode 4 and iOS SDK 5.0, now my iOS projects won't build. The error basically says that the linker can't find the libraries for libbass.a and libbassmidi.a, even though both are included and . For some reason the linker has the options -lbass and -lbassmidi specified; not sure where those came from. The full error is below. Help?!


Ld /Users/AlexanderPease/Library/Developer/Xcode/DerivedData/MetroGnomeiPad-hfodiiugkdazsydieqbgokeedzgq/Build/Products/Debug-iphonesimulator/MetroGnomeiPad.app/MetroGnomeiPad normal i386
    cd /Users/AlexanderPease/git/MetroGnomeiPad
    setenv MACOSX_DEPLOYMENT_TARGET 10.6
    setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -L/Users/AlexanderPease/Library/Developer/Xcode/DerivedData/MetroGnomeiPad-hfodiiugkdazsydieqbgokeedzgq/Build/Products/Debug-iphonesimulator -L/Users/AlexanderPease/git/MetroGnomeiPad -F/Users/AlexanderPease/Library/Developer/Xcode/DerivedData/MetroGnomeiPad-hfodiiugkdazsydieqbgokeedzgq/Build/Products/Debug-iphonesimulator -filelist /Users/AlexanderPease/Library/Developer/Xcode/DerivedData/MetroGnomeiPad-hfodiiugkdazsydieqbgokeedzgq/Build/Intermediates/MetroGnomeiPad.build/Debug-iphonesimulator/MetroGnomeiPad.build/Objects-normal/i386/MetroGnomeiPad.LinkFileList -mmacosx-version-min=10.6 -Xlinker -objc_abi_version -Xlinker 2 -Xlinker -no_implicit_dylibs -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 -framework Foundation -framework UIKit -framework CoreGraphics -framework AudioToolbox -framework CFNetwork -framework SystemConfiguration -framework CoreMIDI -lbass -lbassmidi -o /Users/AlexanderPease/Library/Developer/Xcode/DerivedData/MetroGnomeiPad-hfodiiugkdazsydieqbgokeedzgq/Build/Products/Debug-iphonesimulator/MetroGnomeiPad.app/MetroGnomeiPad

ld: library not found for -lbass
Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang failed with exit code 1
Logged
einsteinx2
Posts: 61


« Reply #332 on: 11 Dec '11 - 00:04 »
Reply with quoteQuote

... xcode4 problems...

Did you just upgrade from Xcode 3?

In Xcode 4 there's no need to set linker flags to use libbass.a. Just make sure it's in your project. Then in the browser on the left, make sure you're in the folder view, and click on your project's name at the top. Click on your build target (must be done for each build target if you have more than one). On right right, go to the Build Phases tab. Open up the "Link Binary with Libraries" phase and drag the libbass.a (and any other .a files) from the folder view on the left into the build phase with the other frameworks.

That's it, it should build now.

edit, also I think if you just place the .a in your Frameworks folder with the other frameworks, Xcode automatically adds it to the correct build phase.
« Last Edit: 11 Dec '11 - 00:45 by einsteinx2 » Logged
einsteinx2
Posts: 61


« Reply #333 on: 11 Dec '11 - 00:07 »
Reply with quoteQuote

Ian, shouldn't all files supported by the iPod app playing using BASS? I'm getting error 41 unsupported file for any ALAC file higher resolution than 16/44.1. These ALAC files play fine in the iPod app as well as with my old code using Audio Queue services. Also any FLAC of higher resolution than 16/44.1 gives error 41 as well.

Also, no matter what sample rate I set in BASS_init, it always sets the output sample rate to 44.1 (as checked with BASS_GetInfo).

Are these issues current limitations of BASS for iOS, or am I doing something wrong?

edit, also having issues opening 16/44.1 alac files from one of my beta testers. None of his ALAC files play.

edit2, weirdly, if I add the BASS_SAMPLE_LOOP flag to the stream, the 16/44.1 alac file that wasn't playing before now plays, but the higher rez files still don't

/// hmm, tested with another 16/44.1 alac file and still not working even with BASS_SAMPLE_LOOP set. Since BASS is using coreaudio for alac files, is it possible that it's not setting something correctly in iOS to use these files? Note all these files work using BASS in OS X using the coreaudio codec.

/// ok removing BASS_SAMPLE_FLOAT, and adding BASS_SAMPLE_LOOP is getting more files to play. So it seems like sometimes it doesn't like opening ALAC streams as FLOAT, sometimes it does. And sometimes streams have to be a LOOP but sometimes they don't. And it still won't open anything that is higher than 16/44.1... I'll keep testing and post more results.

/// Found that adding BASS_SAMPLE_SOFTWARE seems to be letting everything play now! Even high resolution ALAC files.

/// Sad keep speaking too soon. Some ALAC files (not sure why not all) will not play unless the whole file has been downloaded and can not be streamed. These files played fine while streaming using Audio Queue Services.


-----------------------

Only 3 issues now:

1. Anything higher than 96KHz sample rate has a loud white noise in the background. I assume from the downsampling process. It also happens on OS X so it's not an iOS specific thing. Is there anything I can set to make those files downsample without the hiss/white noise?

2. Can't set values higher than 44100 for BASS_init. Anything higher just sets it to 44100. I've confirmed that the iPhone supports 48KHz by setting up an audio session manually in a test project. Anything higher just sets it to 48KHz, so that seems to be the max. BASS however seems to be completely ignoring the sample rate parameter. I've tried 48000, 44100, and 22050 (all supported when setting an audio session manually) and they all set the actual sample rate to 44100. This appears to be a bug in BASS for iOS.

3. Some (but not all) ALAC files and most (possibly all) aac (m4a) files are not playing unless they've been fully downloaded first.
« Last Edit: 12 Dec '11 - 07:06 by einsteinx2 » Logged
Ian @ un4seen
Administrator
Posts: 15363


« Reply #334 on: 12 Dec '11 - 14:55 »
Reply with quoteQuote

Ian, shouldn't all files supported by the iPod app playing using BASS? I'm getting error 41 unsupported file for any ALAC file higher resolution than 16/44.1. These ALAC files play fine in the iPod app as well as with my old code using Audio Queue services. Also any FLAC of higher resolution than 16/44.1 gives error 41 as well.
...
/// Sad keep speaking too soon. Some ALAC files (not sure why not all) will not play unless the whole file has been downloaded and can not be streamed. These files played fine while streaming using Audio Queue Services.

Are you downloading to a local file, and passing that to BASS_StreamCreateFile while it is still downloading? If so, it sounds like there probably wasn't enough pre-downloaded to initialize the decoder. Perhaps you could use BASS_StreamCreateFileUser instead? Something like suggested in this post...

   http://www.un4seen.com/forum/?topic=13185.msg91733#msg91733

Note you shouldn't have to bother with that for FLAC, as it is supported by BASS_StreamCreateURL (when BASSFLAC is loaded). If you would still like to have a local copy of the file, you can get that via a DOWNLOADPROC function provided in the BASS_StreamCreateURL call. If you need to handle the downloading yourself, you could use BASS_StreamCreateFileUser with system=STREAMFILE_BUFFER (or STREAMFILE_BUFFERPUSH) then to play it.

Also, no matter what sample rate I set in BASS_init, it always sets the output sample rate to 44.1 (as checked with BASS_GetInfo).

BASS_Init was ignoring the "freq" parameter and always using the hardware's default sample rate, but an update that will use the requested rate if possible is now up in the package (see the 1st post). You can use BASS_GetInfo to confirm what rate is actually being used.

Anything higher than 96KHz sample rate has a loud white noise in the background.

Please upload a file that is particularly badly affected to have a look at here...

   ftp.un4seen.com/incoming/
Logged
einsteinx2
Posts: 61


« Reply #335 on: 12 Dec '11 - 18:49 »
Reply with quoteQuote

Thank you for such a quick fix for the 48KHz BASS_init issue! I will incorporate the new version today and test out that functionality. edit: setting sample rate is working perfectly now Smiley

I just uploaded a file called 192KHz loud white noise.flac to your ftp. This gives me loud white noise in Vox (a libbass player for OS X), in my app on iOS, as well as using your sample code on OS X. Also I've tried with another file that is 176.4KHz with the same issue. When I convert an offending files to 96KHz, they play perfectly.

I'm streaming using my own networking code to download the file, which I need to do for a few reasons, so using BASS_StreamCreateURL isn't a possibility for me. Then I'm opening the still downloading file using BASS_StreamCreateFile. This works fine for all file formats except the mp4 container (though for whatever reason, certain m4a files with the ALAC codec seem to work, while all AAC codec m4a files fail). I'm aware that the mp4 container has some metadata information at the end of the file, so maybe it needs that metadata to correctly identify the file format? However, since this is not the case using AQS or when streaming the same file in the Chrome browser, it must be technically possible to play mp4 files without the end.

I've done some tests this morning attempting to identify how much of the m4a file needs to be downloaded for playback to work. For an m4a file with aac codec that is 11933258 bytes long, even downloading 11000000 bytes before calling BASS_StreamCreateFile will not work. Always get an error 41, unsupported format. So it looks like, for BASS_StreamCreateFile anyway, it literally needs every byte of the m4a file to detect the format. I've uploaded a test file to your ftp called problem.m4a if you want to test anything.

I'll try implementing BASS_StreamCreateFileUser today and see if that makes any difference, though I notice the person in the thread you referenced seemed to be having a similar issue of needing the whole file in order to play and wasn't able to get it to work with BASS_StreamCreateFileUser.

Is there any way I could supply the format type to BASS manually, rather than having it detect? I know the format type before I call BASS_StreamCreateFile, so I could pass that information and skip the file detection altogether if that's possible.
« Last Edit: 12 Dec '11 - 18:58 by einsteinx2 » Logged
einsteinx2
Posts: 61


« Reply #336 on: 12 Dec '11 - 19:57 »
Reply with quoteQuote

I did some testing with BASS_StreamCreateFileUser to see where it is trying to seek when opening the stream.

Here is the result of two tests:

Test 1: calling BASS_StreamCreateFileUser after approx 2MB done downloading
downloadedLength:  2159669   
seek offset: 94208
[b]seek offset: 2159526[/b]
seek offset: 0
seek offset: 0
seek offset: 0
seek offset: 206788
seek offset: 618916
seek offset: 32
seek offset: 33276
seek offset: 91544
seek offset: 148
seek offset: 40
seek offset: 32
seek offset: 33276
seek offset: 91544
seek offset: 206788
seek offset: 94228
BASS error: 41

Test 2: calling BASS_StreamCreateFileUser after approx 1MB done downloading
downloadedLength:  1143669
[b]seek offset: 1135526[/b]
seek offset: 0
seek offset: 0
seek offset: 0
seek offset: 206788
seek offset: 618916
seek offset: 32
seek offset: 33276
seek offset: 91544
seek offset: 148
seek offset: 40
seek offset: 32
seek offset: 33276
seek offset: 91544
seek offset: 206788
seek offset: 94228
BASS error: 41

As you can see in the bold tags, regardless of how much has been downloaded so far, it tries to read a few bytes before the end of the file. So it must be looking for some kind of data there and when it doesn't find it, it throws an error 41. I'll test some more today and see what I can find.
Logged
einsteinx2
Posts: 61


« Reply #337 on: 12 Dec '11 - 23:46 »
Reply with quoteQuote

Possible solution!

As you suggested in another thread, I switched to using BASS_StreamCreateFileUser, and in my MyFileLenProc function, am returning LLONG_MAX. That seems to be tricking it into playing the file!

I'm going to test with more files and report back.

edit: Tested more files, this fixed every ALAC file I've tried so far with the exception of one, but AAC files still giving error 41. So looks like this isn't a full solution. But getting closer!
« Last Edit: 13 Dec '11 - 00:47 by einsteinx2 » Logged
Ian @ un4seen
Administrator
Posts: 15363


« Reply #338 on: 13 Dec '11 - 16:14 »
Reply with quoteQuote

I just uploaded a file called 192KHz loud white noise.flac to your ftp.

Thanks. I'll look into it and get back to you.

Possible solution!

As you suggested in another thread, I switched to using BASS_StreamCreateFileUser, and in my MyFileLenProc function, am returning LLONG_MAX. That seems to be tricking it into playing the file!

If you know the final file length, it should also be OK to return that (instead of LLONG_MAX) in your FILELENPROC function. That could result in the BASS_ChannelGetLength value being more accurate if the codec is estimating the duration from the file length, eg. with ADTS AAC files.

Tested more files, this fixed every ALAC file I've tried so far with the exception of one, but AAC files still giving error 41. So looks like this isn't a full solution. But getting closer!

Are you pre-downloading a fixed amount of the file, or are you downloading according to what's requested of your FILEREADPROC (and FILESEEKPROC) functions, eg. do you have the FILEREADPROC wait for the requested amount of data? In my tests on this, I found that you can safely ignore seek requests (return FALSE in the FILESEEKPROC) that are a long way ahead during stream creation, ie. while in the BASS_StreamCreateFileUser call. With your problem.m4a example file, the stream creation required 623012 bytes of it.
Logged
einsteinx2
Posts: 61


« Reply #339 on: 13 Dec '11 - 20:22 »
Reply with quoteQuote

I don't always know the final length because the server application could have transcoding enabled, but when transcoding is not enabled (and I have access to a boolean for this) then I do know the exact length. I'll implement that rather than LLONG_MAX for the cases when I do know it. Though I could probably always return the server provided file size, because the transcoded size will always be smaller, so it should work just as well as LLONG_MAX for preventing detection failures.

I'm downloading at a fixed speed in another thread, handled by a custom caching manager. After a certain number of bytes is downloaded, it  calls a method in the BASS wrapper to start playing the song.

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. I could have sworn I tested using both 1024 KB and 2048 KB before and it wasn't working, but I guess I was testing something else because it's working now. Also the one ALAC file I was having trouble with is also working.

So it looks like what I'll need to do is add a mechanism to start trying to play the files around 250 KB (which works fine for most formats) but then retry every couple hundred KB if it fails.

Thanks for all the help! I'll continue to test with more files and report back any issues I run into, if any.

edit: looks like using the server reported file size for the file length callback is working great as long as enough of the file has been downloaded to perform the identification Smiley
« Last Edit: 13 Dec '11 - 22:48 by einsteinx2 » Logged
Pages: 1 ... 15 16 [17] 18 19 ... 37
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines