Skip to content

Instantly share code, notes, and snippets.

View theoknock's full-sized avatar

James Alan Bush theoknock

View GitHub Profile
@theoknock
theoknock / nested_block_literals.m
Last active August 22, 2020 21:23
Block literals as parameters to an enclosing block as a substitute for dispatch groups, allowing synchronization of an aggregate of tasks. There are two task aggregates: one supplies the value for d1; the other, c2; They are notated by 1 and 2, respectively; the letters (a through d, a through c) mark the progression of the tasks in each aggregate.
^(int d1, int(^c2)(void))
{
return c2;
} (^(int c1)
{
return c1;
} (^(int b1)
{
return b1;
} (a1)),
@theoknock
theoknock / normalize.m
Last active August 28, 2020 19:39
Scales values within a given range to a value between 0 and 1 (normalization)
double (^normalize)(double, double, double) = ^double(double min, double max, double value)
{
double result = (value - min) / (max - min);
return result;
};
@theoknock
theoknock / scale.m
Created August 28, 2020 19:38
Scales values within one range to another range
double (^scale)(double, double, double, double, double) = ^double(double min_new, double max_new, double value, double min_old, double max_old)
{
double result = min_new + ((((value - min_old) * (max_new - min_new))) / (max_old - min_old));
return result;
};
@theoknock
theoknock / BufferSamples.m
Last active August 29, 2020 14:06
Initializes a two-channel (stereo) PCM audio buffer for computed audio data (versus pre-recorded audio)
AVAudioPCMBuffer * (^bufferSamples)(AVAudioFrameCount, AVAudioChannelCount, AVAudioFormat *, double) = ^AVAudioPCMBuffer *(AVAudioFrameCount frame_count, AVAudioChannelCount channel_count, AVAudioFormat *audioFormat, double duration_n_secs)
{
AVAudioFrameCount frameCount = audioFormat.sampleRate * duration;
AVAudioPCMBuffer *pcmBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFormat frameCapacity:frameCount];
pcmBuffer.frameLength = frameCount;
float *left_channel = pcmBuffer.floatChannelData[0];
float *right_channel = (channelCount == 2) ? pcmBuffer.floatChannelData[1] : nil;
int amplitude_frequency = arc4random_uniform(8) + 4;
for (int index = 0; index < frame_count; index++)
@theoknock
theoknock / Math.h
Last active September 2, 2020 02:49
A factory for blocks that all perform different math operations—either addition or subtraction—using a common interface. The abstract block defines the interface for the blocks that implement the specified functionality (the math operation).
#ifndef Math_h
#define Math_h
#include <stdarg.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
// A block that performs a given mathematical operation, encapsulated in a struct
@theoknock
theoknock / base_struct.c
Last active August 30, 2020 07:14
Super- and sub-classing C structs
// A "base struct" from which other "substructs" will inherit
typedef struct {
int value;
} base_struct;
@theoknock
theoknock / init_pcm_buffer.m
Last active September 1, 2020 10:26
Uses a series of chained block literals to compute a data representation of a sine wave and store it in an AVAudioPCMBuffer, which is scheduled for playback via an AVAudioPlayerNode. After playback, the process repeats, generating a continuous series of tones (until, for example, the AVAudioPlayerNode is paused).
typedef void (^PlayedToneCompletionBlock)(void);
typedef void (^BufferRenderedCompletionBlock)(AVAudioPlayerNode * _Nonnull player_node, AVAudioPCMBuffer * _Nonnull buffer, PlayedToneCompletionBlock _Nonnull playedToneCompletionBlock);
static void(^createAudioBuffer)(AVAudioPlayerNode *, AVAudioSession *, AVAudioFormat *, BufferRenderedCompletionBlock) = ^(AVAudioPlayerNode * player_node, AVAudioSession * audioSession, AVAudioFormat * audioFormat, BufferRenderedCompletionBlock bufferRenderedCompletionBlock)
{
// playerNode buffer scheduler goes here
[player_node scheduleBuffer:^AVAudioPCMBuffer * (void (^buffer_sample)(AVAudioFrameCount, double, double, double, float *, AVAudioChannelCount))
{
double duration = random_source_drand48(0.25, 1.75);;
AVAudioFrameCount frameCount = ([audioFormat sampleRate] * duration);
@theoknock
theoknock / custom_dispatch_source.m
Last active September 16, 2020 08:37
Passing context data via a custom dispatch source (basic)
// Prints 'x = 2.0' to the Console log
#import "custom_dispatch_source.h"
typedef struct ContextData
{
double x;
} ContextData;
@interface custom_dispatch_source ()
@theoknock
theoknock / cmtime_to_nsstring.m
Created September 22, 2020 02:08
Converting current CMTime to NSString
typedef CMTime(^CurrentCMTime)(void);
static CurrentCMTime _Nonnull current_cmtime = ^ CMTime (void) {
return CMClockGetTime(CMClockGetHostTimeClock());
};
typedef NSString * _Nonnull (^StringFromTime)(CMTime);
static StringFromTime _Nonnull cmTimeString = ^ NSString * (CMTime cm_time) {
NSString *stringFromCMTime;
float seconds = round(CMTimeGetSeconds(cm_time));
int hh = (int)floorf(seconds / 3600.0f);
@theoknock
theoknock / DoubleConversionExtensions.swift
Last active May 5, 2021 16:34
Convert degrees to radians
import Foundation
extension Double {
var radians: Double { return Measurement(value: self, unit: UnitAngle.degrees).converted(to: UnitAngle.radians).value }
var degrees: Double { return Measurement(value: self, unit: UnitAngle.radians).converted(to: UnitAngle.degrees).value }
}