Skip to content

Instantly share code, notes, and snippets.

@theoknock
Created July 18, 2022 00:39
Show Gist options
  • Save theoknock/639d314e57aa8f27cc73a1dfe6540b82 to your computer and use it in GitHub Desktop.
Save theoknock/639d314e57aa8f27cc73a1dfe6540b82 to your computer and use it in GitHub Desktop.
AVFAudio manual rendering, abbreviated. The most concise implementation of manual audio buffer rendering using AVFoundation, using only an AVAudioSourceNode and nothing else. Plays white noise for one second.
#import "ViewController.h"
@import AVFoundation;
@interface ViewController () {
AVAudioEngine * engine;
AVAudioSourceNode * whiteNoiseGenerator;
}
@end
@implementation ViewController
static Float32 (^(^(^randomize)(void))(Float32(^)(Float32)))(void) = ^{
srand48((unsigned int)time(0));
return ^ (Float32(^scale)(Float32)) {
static Float32 random;
return ^ Float32 {
return (Float32)scale((random = drand48()));
};
};
};
static Float32 (^rescale)(Float32) = ^ Float32 (Float32 distributed_random) {
Float32 range_max = 1.f, range_min = -1.f;
return (distributed_random = (distributed_random * (range_max - range_min)) + range_min);
};
static Float32 (^whiteNoise)(void);
- (void)viewDidLoad {
[super viewDidLoad];
whiteNoise = randomize()(rescale);
whiteNoiseGenerator = [[AVAudioSourceNode alloc] initWithRenderBlock:^OSStatus(BOOL * _Nonnull isSilence, const AudioTimeStamp * _Nonnull timestamp, AVAudioFrameCount frameCount, AudioBufferList * _Nonnull outputData) {
Float32 * output_data_t = (Float32 *)outputData->mBuffers[0].mData;
static Float32 value;
for (AVAudioFrameCount frame = 0; frame < frameCount; frame++) {
output_data_t[frame] = (value = whiteNoise());
};
return (OSStatus)noErr;
}];
engine = [[AVAudioEngine alloc] init];
[engine attachNode:whiteNoiseGenerator];
[engine connect:whiteNoiseGenerator to:engine.mainMixerNode format:nil];
engine.mainMixerNode.outputVolume = 1.0;
__autoreleasing NSError * error = nil;
@try {
!([engine startAndReturnError:&error] && !error) ?: sleep(1);
} @catch (NSException *exception) {
printf("\n%s\n", [[exception debugDescription] UTF8String]);
} @finally {
(![engine isRunning]) ?: [engine stop];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment