Skip to content

Fix "bad_access error" when playing short time at high frequency with fade out#96

Open
Kta-M wants to merge 1 commit intokstenerud:masterfrom
Kta-M:fix_high_freq
Open

Fix "bad_access error" when playing short time at high frequency with fade out#96
Kta-M wants to merge 1 commit intokstenerud:masterfrom
Kta-M:fix_high_freq

Conversation

@Kta-M
Copy link
Copy Markdown

@Kta-M Kta-M commented Feb 15, 2016

I fixed a bug regarding the error: "EXC_BAD_ACCESS" which made the app crashed.
It occurs when playing sound short time at high frequency with fade out.
(at ObjectAL/ObjectAL/Actions/OALActionManager.m#L160)

When starting fade out, a fade action added to OALActionManager targetActions, and it removed when fade out was completed. However, there is a time lag between releasing ALSource and removing fade action from targetActions.

App crashes during the time lag when a new ALSource is generated with the same id as the released old AlSource one and when an action from the ALSource is added to the to the targetActions.

Regarding the OALActionManager step:timer, when a new fade action from the ALSource is attempting to be added, the id of the released ALSource however remains present in the targets. Therefore, the new fade action is added to the array of actions for old ALSource in targetActions. Next, the fade action of released ALSource is removed, but the id of released ALSource is not removed from targets because the fade action of new ALSource remains in the array of actions in targetActions. Hence the next time OALActionManager step:timer is called, the app will crash trying to reference the id of released ALSource in targets.

To fix it, I swapped the order of adding and removing actions in the code, and removed the master timer stop condition and placed it out, at the end of the adding/removing process.

The following code is for verification. It reproduces this bug.

class SampleClass: NSObject {

    let buffer = OpenALManager.sharedInstance().bufferFromFile("sample.wav")
    var sourceArray: Array<ALSoundSource> = []
    var playingSource: ALSoundSource?

    func play() {
        NSTimer.scheduledTimerWithTimeInterval(1.0/60.0, target: self, selector: "update:", userInfo: nil, repeats: true)
    }

    func update(timer: NSTimer) {
        playingSource?.fadeTo(0.0, duration: 0.5, target: self, selector: "onFadeComplete:")

        let source = ALSource.source() as? ALSoundSource
        source!.play(buffer, gain: 1.0, pitch: 1.0, pan: 1.0, loop: false)
        sourceArray.append(source!)
        playingSource = source
    }

    func onFadeComplete(source: ALSoundSource) {
        let index = sourceArray.indexOf{ $0.hash == source.hash }
        sourceArray.removeAtIndex(index!)
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant