19 Jun '13 - 23:59 *
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 ... 24 25 [26] 27 28 ... 37
  Reply  |  Print  
Author Topic: BASS for iOS (iPhone/iPad)  (Read 115646 times)
Ian @ un4seen
Administrator
Posts: 15366


« Reply #500 on: 7 Jun '12 - 16:19 »
Reply with quoteQuote

Updated BASS and BASSmix builds are up in the first post, including NEON-optimized sinc interpolation for a nice performance boost on NEON-supporting devices (those using the ARMv7 architecture).

For another performance boost on ARMv7, BASS has also switched to the OS's Accelerate framework for FFT processing. So that framework should be added to your Xcode projects. It requires iOS 4, and BASS_ChannelGetData will fail (BASS_ERROR_NOTAVAIL) if FFT data is requested on an older iOS version. BASS's own FFT processing is still used on ARMv6, as some ARMv6 devices can't be upgraded to iOS 4, ie. 1st gen iPhone/iPod Touch.
Logged
einsteinx2
Posts: 61


« Reply #501 on: 11 Jun '12 - 21:14 »
Reply with quoteQuote

Regarding the previous issues I posted, you're correct the file I sent would not sync to the device, but that was because it was missing the container. Once I used MP4Box to add an mp4 container, it would sync and BASS would play it. So sorry to bother you with that one.

As for the crash with the file being mis-identified as an MPC file, I've only had it happen to me once, and I can't remember on which song, as I've only received one crash report from a user, but it was automatic and so I don't know what song it was. If/when I can get it to happen in testing again, I'll send you the file.

However, today I discovered another issue and it is reproducible every time. I'm having an issue with seeking in 22.05KHz he-aac files with mp4 container. If I seek past about halfway, the file len proc gets called over and over in an infinite loop. The stack trace shows it's being called by BASS_FX_TempoCreate but that must be happening internally in BASS. It seems like the seek actually works, but then the len proc getting called over and over causes that thread to block and the audio stops, but a half second will stutter in once in a while.

I'll message you a link to a test file, this happens even with the latest update you posted.

edit: actually after inspecting the file, it is apparantly a 44.1KHz file, but BASS is detecting it as 22.05. I confirmed that ffmpeg and vlc correctly recognize as 44.1Khz, but Vox a Mac audio player that uses BASS, also detects incorrectly as 22.05. This is happening on various different files, but only the one i sent you so far exhibits the seek len proc loop issue.
« Last Edit: 11 Jun '12 - 21:35 by einsteinx2 » Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #502 on: 12 Jun '12 - 16:05 »
Reply with quoteQuote

However, today I discovered another issue and it is reproducible every time. I'm having an issue with seeking in 22.05KHz he-aac files with mp4 container. If I seek past about halfway, the file len proc gets called over and over in an infinite loop. The stack trace shows it's being called by BASS_FX_TempoCreate but that must be happening internally in BASS. It seems like the seek actually works, but then the len proc getting called over and over causes that thread to block and the audio stops, but a half second will stutter in once in a while.

I'll message you a link to a test file, this happens even with the latest update you posted.

A FILELENPROC function will be called whenever a CoreAudio codec delivers less sample data than was requested, to check whether it's reached the end of the file. Is your FILEREADPROC function delivering the requested amount of file data following the seek request? If not, that would explain the AAC codec delivering less than requested, and your FILELENPROC function subsequently being called. That would be likely to result in playback stopping/stalling (due to lack of data to play), but it shouldn't block the thread.

To see whether the problem may be related to your file handling code, what happens if you use BASS_StreamCreateFile to play the file instead? If that's fine and you're still having trouble with your code, please confirm what your BASS_StreamCreateFileUser call and BASS_FILEPROCS functions look like.

Regarding the call stack showing BASS_FX_TempoCreate, that will be the closest public function preceding the frame's location, which isn't necessarily a true reflection of what function it's in. The BASS libraries don't include debugging symbols, so the debugger doesn't know about internal functions. For example, if there are functions arranged like this: publicA, privateB, publicC. And a call stack frame is in privateB, it will be reported as being in publicA because the debugger doesn't know about privateB. A debugger will usually show an offset with the function name, which can be a clue for how reliable it is, ie. a low offset makes it more likely that the function is accurate.

edit: actually after inspecting the file, it is apparantly a 44.1KHz file, but BASS is detecting it as 22.05. I confirmed that ffmpeg and vlc correctly recognize as 44.1Khz, but Vox a Mac audio player that uses BASS, also detects incorrectly as 22.05. This is happening on various different files, but only the one i sent you so far exhibits the seek len proc loop issue.

BASS doesn't actually detect the sample rate of AAC files itself, but rather follows what the CoreAudio codec reports. With the 2 example files that you provided, it is indeed reporting a sample rate of 22050 Hz. It is the same in iTunes. There must be something about the files that's making the codec think they're plain AAC rather than HE-AAC. I'm not sure there is any way around that, unfortunately.
Logged
einsteinx2
Posts: 61


« Reply #503 on: 13 Jun '12 - 22:10 »
Reply with quoteQuote

I'll investigate the FILELENPROC issue based on the information you've provided, and report back.

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

You're absolutely right about CoreAudio, turns out MP4Box write incorrect mp4 container information, sorry to waste your time on that. For anyone else that may come across this issue, I was able to solve it using ffmpeg to do the container and pyqtfaststart to move the MOOV atom to the beginning to allow for progressive streaming (MP4Box does that automatically, but ffmpeg doesn't).

I used the following commands (note this also works if the input file is a raw aac file instead of already in mp4 container):

ffmpeg -i song.m4a -acodec copy song.m4a.new && rm song.m4a && mv song.m4a.new song.m4a && qtfaststart song.m4a
Logged
puzzler
Posts: 5


« Reply #504 on: 15 Jun '12 - 09:17 »
Reply with quoteQuote

Do bass support "mute" switch on iOS? Or we have to track this event by progamm?
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #505 on: 15 Jun '12 - 14:29 »
Reply with quoteQuote

For the mute switch to affect your app, I think it needs to be using an "ambient" audio session category. BASS doesn't do that by default, but it can be told to do so via the BASS_CONFIG_IOS_MIXAUDIO config option, like this...

BASS_SetConfig(BASS_CONFIG_IOS_MIXAUDIO, 5);

Please see the first post for the possible BASS_CONFIG_IOS_MIXAUDIO settings.
Logged
Delphinus
Posts: 39


« Reply #506 on: 15 Jun '12 - 15:45 »
Reply with quoteQuote

Hi,

I continue with vinyl scratching issue. The only remaining problem is that when scratching slowly I got crackle sounds. This may be related to CONFIG_BUFFER or CONFIG_UPDATEPERIOD, but I don't rellay know which values are possibly correct.

I've setted these values

BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 15);
 BASS_SetConfig(BASS_CONFIG_BUFFER, 100);

May be there are others explanations to crackle sounds? any ideas?
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #507 on: 15 Jun '12 - 18:00 »
Reply with quoteQuote

Please confirm how you have implemented the scratching. If I recall correctly, you were previously using your own scratching/reverse implementation rather than the BASS_FX stuff? Also, does the "crackle" occur when the playback direction changes?

Regarding your UPDATPERIOD and BUFFER settings, they look like they should be fine in most cases. You could possibly increase the UPDATEPERIOD a little, to reduce CPU usage a little (each update cycle will have some overhead). Setting UPDATEPERIOD to around a third of the BUFFER value should be sufficient to keep the buffer reasonably full at all times (at least 2 thirds full). Note neither of these settings matter very much when BASS_ATTRIB_NOBUFFER is enabled.
Logged
puzzler
Posts: 5


« Reply #508 on: 15 Jun '12 - 19:39 »
Reply with quoteQuote

For the mute switch to affect your app, I think it needs to be using an "ambient" audio session category. BASS doesn't do that by default, but it can be told to do so via the BASS_CONFIG_IOS_MIXAUDIO config option, like this...

BASS_SetConfig(BASS_CONFIG_IOS_MIXAUDIO, 5);

Please see the first post for the possible BASS_CONFIG_IOS_MIXAUDIO settings.

Thanks! It works now.
Logged
Delphinus
Posts: 39


« Reply #509 on: 18 Jun '12 - 09:34 »
Reply with quoteQuote

You told me to read the topic named "Vinyl scratching demo" so I read it. I implemented the scratching and it works fine at least when I reverse or forward scratching it really changes at the correct position.

The only thing I want to do is to hear the real scracthing as we did in a real turntable.

The crackle sound occurs when I scratch slowly in both directions:

Here's my scratching code:

if (scratchVelocity < 100 && scratchVelocity > -100000)
    {
        BASS_ChannelStop([bassPointer getChannel]);
        BASS_ChannelSetPosition([bassPointer getChannel], initialScratchPos + angleAccum, BASS_POS_BYTE | BASS_POS_DECODE);
        BASS_ChannelSetAttribute([bassPointer getRevChannel], BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_REVERSE);
        BASS_ChannelPlay([bassPointer getChannel], false);
        NSLog(@"scratchVelocity %f", -scratchVelocity);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, -scratchVelocity, 100);
       
    }
    else if (scratchVelocity > 100 && scratchVelocity < 100000)
    {
        BASS_ChannelStop([bassPointer getChannel]);
        BASS_ChannelSetPosition([bassPointer getChannel], initialScratchPos + angleAccum, BASS_POS_BYTE | BASS_POS_DECODE);
        BASS_ChannelSetAttribute([bassPointer getRevChannel], BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_FORWARD);
        BASS_ChannelPlay([bassPointer getChannel], false);
        NSLog(@"scratchVelocity %f", scratchVelocity);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, scratchVelocity, 100);
    }

The 'initialScratchPos' variable is the position in bytes when I start the scratching and 'angleAccum' variable is the number of bytes to add to have the correct position while scratching.

When the freq parameter is out of range (100 < freq < 100000):

BASS_ChannelStop([bassPointer getChannel]);
        BASS_ChannelPlay([bassPointer getChannel], false);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, 88200, 100);
« Last Edit: 18 Jun '12 - 10:03 by Delphinus » Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #510 on: 18 Jun '12 - 15:01 »
Reply with quoteQuote

The crackle sound occurs when I scratch slowly in both directions:

Do you still hear crackling if you leave the playback going slowly forward or backward? Or does it only occur when you change direction while playback is going slowly?

The 'initialScratchPos' variable is the position in bytes when I start the scratching and 'angleAccum' variable is the number of bytes to add to have the correct position while scratching.

How are you calculating the "angleAccum" value? What happens if you remove the BASS_ChannelStop and BASS_ChannelSetPosition calls from your code, like this?

if (scratchVelocity < 100 && scratchVelocity > -100000)
    {
        BASS_ChannelSetAttribute([bassPointer getRevChannel], BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_REVERSE);
        NSLog(@"scratchVelocity %f", -scratchVelocity);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, -scratchVelocity, 100);
       
    }
    else if (scratchVelocity > 100 && scratchVelocity < 100000)
    {
        BASS_ChannelSetAttribute([bassPointer getRevChannel], BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_FORWARD);
        NSLog(@"scratchVelocity %f", scratchVelocity);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, scratchVelocity, 100);
    }

Another thing you could try is this...

if (scratchVelocity < 100 && scratchVelocity > -100000)
    {
        BASS_ChannelStop([bassPointer getChannel]);
        QWORD pos=BASS_ChannelGetPosition([bassPointer getChannel], BASS_POS_BYTE); // get current position
        BASS_ChannelSetPosition([bassPointer getChannel], pos, BASS_POS_BYTE); // "seek" there to clear output buffer (avoid latency)
        BASS_ChannelSetAttribute([bassPointer getRevChannel], BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_REVERSE);
        BASS_ChannelPlay([bassPointer getChannel], false);
        NSLog(@"scratchVelocity %f", -scratchVelocity);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, -scratchVelocity, 100);
       
    }
    else if (scratchVelocity > 100 && scratchVelocity < 100000)
    {
        BASS_ChannelStop([bassPointer getChannel]);
        QWORD pos=BASS_ChannelGetPosition([bassPointer getChannel], BASS_POS_BYTE);
        BASS_ChannelSetPosition([bassPointer getChannel], pos, BASS_POS_BYTE);
        BASS_ChannelSetAttribute([bassPointer getRevChannel], BASS_ATTRIB_REVERSE_DIR, BASS_FX_RVS_FORWARD);
        BASS_ChannelPlay([bassPointer getChannel], false);
        NSLog(@"scratchVelocity %f", scratchVelocity);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, scratchVelocity, 100);
    }

By the way, I guess you have this stream arrangement: decoder (BASS_StreamCreateFile) -> reverse (BASS_FX_ReverseCreate) -> tempo (BASS_FX_TempoCreate). And "getRevChannel" gives the reverse stream handle, and "getChannel" gives the tempo stream handle. Is that correct?

Please also confirm when the following comes into play...

When the freq parameter is out of range (100 < freq < 100000):

BASS_ChannelStop([bassPointer getChannel]);
        BASS_ChannelPlay([bassPointer getChannel], false);
        BASS_ChannelSlideAttribute([bassPointer getChannel], BASS_ATTRIB_FREQ, 88200, 100);

Wouldn't "100 < freq < 100000" be covered by "scratchVelocity > 100 && scratchVelocity < 100000"?
Logged
Delphinus
Posts: 39


« Reply #511 on: 18 Jun '12 - 15:19 »
Reply with quoteQuote

Lol I kinda feel stupid. your first solution was correct. I thought I had to use Bass_ChannelStop to flush buffers.

angleAccum is calculated like this:

float GetBestAngleDiff(float a)
{
float a1 = a - 2.0f * M_PI;
float a2 = a + 2.0f * M_PI;

if (fabsf(a) < fabsf(a1))
{
if (fabsf(a) < fabsf(a2))
return a;

return a2;
}

if (fabsf(a2) < fabsf(a1))
return a2;

return a1;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch* touch = [touches anyObject];
CGPoint position = [touch locationInView:self.superview];

const float angle = -atan2f(position.x - 160.0f, position.y - 240.0f);

if (isnan(prevAngle))
prevAngle = angle;

const float diff = Sys::GetBestAngleDiff(angle - prevAngle) / 0.00001f;
angleAccum += diff;
prevAngle = angle;


In your second solution, what could be the difference from the first one?

Your guess is right about getRevChannel and my stream arrangement

The 'scratchVelocity' can be out of range when you move the jog wheel very fast (forward or reverse), then the value could be for example: 230000 or -230000
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #512 on: 18 Jun '12 - 17:21 »
Reply with quoteQuote

In your second solution, what could be the difference from the first one?

The 2nd suggestion will clear the playback buffer (via the BASS_ChannelSetPosition calls), while the 1st won't. If the buffer is small enough (determined by BASS_CONFIG_BUFFER), then the latency may be low enough not to need the buffer cleared during direction changes.
Logged
Delphinus
Posts: 39


« Reply #513 on: 18 Jun '12 - 22:15 »
Reply with quoteQuote

Ok it is good to know for later purpose Wink

In any case thank you, you helped me a lot! Great lib!

I'll come with other questions soon if needed Wink
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #514 on: 19 Jun '12 - 16:33 »
Reply with quoteQuote

I look forward to it Wink
Logged
Delphinus
Posts: 39


« Reply #515 on: 21 Jun '12 - 11:07 »
Reply with quoteQuote

Here's the other question you were looking forward ^^

For the scratching stuff I need very small buffer so that's what I did setting:

BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 5);
BASS_SetConfig(BASS_CONFIG_BUFFER, 15);

When scratching slow it is fine but when the channel is playing normally it gets choppy. I don't know which values I have to set to have a very accurate thing and a normal playing.
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #516 on: 21 Jun '12 - 13:40 »
Reply with quoteQuote

For the minimum latency, you could try enabling the BASS_ATTRIB_NOBUFFER option instead, like this...

BASS_ChannelSetAttribute([bassPointer getChannel], BASS_ATTRIB_NOBUFFER, 1);

Please see the documentation for details. Note when that's enabled, update threads/cycles aren't needed, so you can save a bit of CPU by disabling them (set BASS_CONFIG_UPDATETHREADS to 0 via BASS_SetConfig).
Logged
Delphinus
Posts: 39


« Reply #517 on: 21 Jun '12 - 14:08 »
Reply with quoteQuote

Hmm I don't have BASS_ATTRIB_NOBUFFER attribute... where can I find it?
Logged
Delphinus
Posts: 39


« Reply #518 on: 21 Jun '12 - 14:17 »
Reply with quoteQuote

Oups Just got a weird .h. It works now lol. It seems that all my problem are solved easily xD. Thanks again and again. By curiosity how does it works internally?
Logged
Ian @ un4seen
Administrator
Posts: 15366


« Reply #519 on: 21 Jun '12 - 16:53 »
Reply with quoteQuote

Good to hear it's working now.

Regarding BASS_ATTRIB_NOBUFFER... when it is enabled on a channel, BASS will skip the buffering stage (eg. update cycles) on that channel and instead request data from it in the final mix generation stage (when the playing channels are mixed together and sent to the output device). Some additional details can be found in the BASS_ATTRIB_NOBUFFER documentation.
Logged
Pages: 1 ... 24 25 [26] 27 28 ... 37
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines