Skip to content

Instantly share code, notes, and snippets.

@webmonch
Last active June 10, 2024 16:42
Show Gist options
  • Save webmonch/5cce8ad2a612941e4e327db89edcea7f to your computer and use it in GitHub Desktop.
Save webmonch/5cce8ad2a612941e4e327db89edcea7f to your computer and use it in GitHub Desktop.
append buffer example
- (void)viewDidLoad {
[super viewDidLoad];
Superpowered::Initialize("ExampleLicenseKey-WillExpire-OnNextUpdate");
Superpowered::AdvancedAudioPlayer::setTempFolder([NSTemporaryDirectory() fileSystemRepresentation]);
audioIO = [[SuperpoweredIOSAudioIO alloc] initWithDelegate:(id<SuperpoweredIOSAudioIODelegate>)self preferredBufferSize:12 preferredSamplerate:44100 audioSessionCategory:AVAudioSessionCategoryPlayback channels:2 audioProcessingCallback:audioProcessing clientdata:(__bridge void *)self];
[audioIO start];
compressedAudioBuffer = (Superpowered::AudioInMemory*)Superpowered::AudioInMemory::create(0, 0, 0, false);
player = new Superpowered::AdvancedAudioPlayer(44100, 0);
currentChunkIndex = 0;
bytesDownloaded = 0;
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onDisplayLink)];
displayLink.preferredFramesPerSecond = 60;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[self downloadChunks];
}
- (void)downloadChunks {
if (currentChunkIndex == CHUNK_COUNT) {
NSLog(@"All chunks downloaded");
return;
}
// wait for few chunks so there is at least few seconds of audio to play
if (currentChunkIndex == 2) {
player->openMemory(compressedAudioBuffer);
}
NSURL *url = [NSURL URLWithString:[NSString stringWithUTF8String:chunks[currentChunkIndex]]];
NSLog(@"Downloading chunk: %i", currentChunkIndex);
currentChunkIndex++;
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Download error: %@", error.localizedDescription);
} else {
if (data) {
unsigned long byteCount = (unsigned long)[data length];
bytesDownloaded += byteCount;
// append() takes ownership of this memory
void* bytesBuffer = malloc(byteCount);
memcpy(bytesBuffer, [data bytes], byteCount);
Superpowered::AudioInMemory::append(compressedAudioBuffer, bytesBuffer, byteCount);
Superpowered::AudioInMemory::setSize(compressedAudioBuffer, bytesDownloaded);
if (currentChunkIndex == 4) {
// simulate network delay
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^{
[self downloadChunks];
});
} else {
[self downloadChunks];
}
}
}
}];
[dataTask resume];
}
static bool audioProcessing(void *clientdata, float *input, float *output, unsigned int numberOfFrames, unsigned int samplerate, uint64_t hostTime) {
__unsafe_unretained ViewController *self = (__bridge ViewController *)clientdata;
self->player->outputSamplerate = samplerate;
bool notSilence = self->player->processStereo(output, false, numberOfFrames);
return notSilence;
}
- (void)onDisplayLink {
switch (player->getLatestEvent()) {
case Superpowered::AdvancedAudioPlayer::PlayerEvent_Opened:
{
NSLog(@"Event Opened");
player->play();
}
break;
default:;
};
}
- (IBAction)onPlay:(id)sender {
player->seek(0);
player->play();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment