Open AndrewRudyk opened 1 month ago
Could you please try with the latest update to the SuperpoweredIOSAudioIO class?
Could you please try with the latest update to the SuperpoweredIOSAudioIO class?
Hello! I'll check it and get back to you with the results. We will have more results after we release the app. Thank you.
Hello, I updated Superpowered SDK to 2.2.8 and sent our app to AppStore. And I see current statistics in Firebase,
But something still goes wrong:)
I saw comment in SuperpoweredIOSAudioIO
Perhaps this problem is still too common
Some memory handling is wrong in your Superpowered.mm file, and therefore the Superpowered features you're using are crashing. Please check your buffer sizes.
Hello, I took code for Superpowered.mm from your examples in repo and preferredBufferSize == 12 took from repo too. How can I change or check the preferredBufferSize?
I use effect objects (Recorder, Flanger, Filter, etc) from SuperpoweredSDK in chain.
- (void)startProcessing {
if (audioIO == nil) {
audioIO = [[SuperpoweredIOSAudioIO alloc] initWithDelegate:(id<SuperpoweredIOSAudioIODelegate>)self
preferredBufferSize:12
preferredSamplerate:mySamplerate
audioSessionCategory:AVAudioSessionCategoryPlayAndRecord
channels:2
audioProcessingCallback:audioProcessing
clientdata:(__bridge void *)self];
[audioIO start];
}
}
// ...
// This code crashes
// SuperpoweredIOSAudioIO calls this closure
static bool audioProcessing(void *clientdata, float *input, float *output, unsigned int numberOfFrames, unsigned int samplerate, uint64_t hostTime) {
__unsafe_unretained SuperpoweredBridge *self = (__bridge SuperpoweredBridge *)clientdata;
if (self->limiter) {
self->limiter->samplerate = samplerate;
self->limiter->process(input, input, numberOfFrames);
}
if (self->compressor) {
self->compressor->samplerate = samplerate;
self->compressor->process(input, input, numberOfFrames);
}
// preparing for recording
self->playerA->outputSamplerate = samplerate;
if (self->_recording && !self->recorderIsPrepared) {
self->recorderIsPrepared = self->recorder->prepare(self->test2Url, samplerate, false, 0);
}
if (self->_recording) {
self->recorder->recordInterleaved(input, numberOfFrames);
}
if (self->spVoicetune) {
self->spVoicetune->samplerate = samplerate;
self->spVoicetune->process(input, input, true, numberOfFrames);
}
if (self->timeStretching) {
self->timeStretching->samplerate = samplerate;
self->timeStretching->addInput(input, numberOfFrames);
self->timeStretching->getOutput(input, numberOfFrames);
}
if (self->threeBandEQ) {
self->threeBandEQ->samplerate = samplerate;
self->threeBandEQ->process(input, input, numberOfFrames);
}
// ...
if (self->echo) {
self->echo->samplerate = samplerate;
self->echo->process(input, input, numberOfFrames);
}
if (self->delayIsEnabled) {
self->delay->samplerate = samplerate;
const float *delayOutput = self->delay->process(input, numberOfFrames);
memcpy(input, delayOutput, numberOfFrames * sizeof(float) * 2);
}
// ...
if (self->_recording) {
Superpowered::Volume(input, output, 0.6f, 0.6f, numberOfFrames);
self->playerA->processStereo(output, true, numberOfFrames, 0.6f);
}
return true;
}
Two things at first glance:
recorder->prepare(...)
on the real-time thread. (Check here)float *input
is not NULL. If for some reason the audio system can't render into the input buffers, it can be NULL.Two things at first glance:
- You shouldn't call
recorder->prepare(...)
on the real-time thread. (Check here)- It would be wise to check if
float *input
is not NULL. If for some reason the audio system can't render into the input buffers, it can be NULL.
I have two notes and questions:
I had to move 'recorder->prepare(...)' from another Prepare function to this location because 'static bool audioProcessing(...)' returned a different Samplerate value than '- (void)startProcessing'. For example, I had set 48000 in '- (void)startProcessing', 'static bool audioProcessing(...)' returned 44100 and I had problems in recording.
If the input can be NULL, why do the crashes not occur at the beginning of the chain?
Hello, I have a question: SuperpoweredSDK's objects modify input-data in "static bool audioProcessing(...)" by chain. One of the objects modifies data in such a way that next object can fail when using this data. How can I check this data and fix it?
Hey Andrew!
Best way would be to log specific edge points of the buffer that goes through the chain and capture where it might go wrong. Something seems to be amiss at some point, so definitely a good idea to log the buffer.
Also, you could use a fixed sample rate on the recorder when preparing, and use a Resampler if the actual sample rate differs in the real-time loop.
Hello Ivan! Could you please explain how to define specific edge points of the buffer. Thank you very much!
Log values around the supposed end of the buffer, check if values get messed up that causes one of the steps in the chain to crash.
Hey @AndrewRudyk, any updates from your side?
Hi I don't have any updates, I haven't researched it from your point of view yet.
I'll return to this topic next spring, when I'm preparing for the next release.
Sorry
Superpowered version: 2.6.6
Describe the bug My app uses Superpowered SDK to create different effects: AutomaticVocalPitchCorrection, ThreeBandEQ, TimeStretching, Bitcrusher, etc. Now I have a lot of reports from Firebase Crashlytics
A lot of problems arise in the variable "samplerate" from class SuperpoweredIOSAudioIO that comes with the SDK.
Xcode shows a lot of Warnings in this class, for example "This code path does interprocess communication underneath which can cause non-deterministic delays. Investigate ways to do this work off the main thread
There are reports of this code path causing UI hangs. See Xcode Organizer for details . Look for the report that shows calls to -[AVAudioSession currentRoute] underneath"
I think that SuperpoweredIOSAudioIO writes incorrect data to the samplerate variable, which is then used by other SuperpoweredSDK objects.
Can you fix this?
Steps to Reproduce Due to the nature of the bug, the reproduction paths vary, and the crash does not happen predictably, making it challenging to outline specific steps to trigger the issue.
Device information Please list which devices have this bug.