Skip to content

Instantly share code, notes, and snippets.

@slmjkdbtl
Last active January 27, 2021 21:05
Show Gist options
  • Save slmjkdbtl/edfd41b6e828bedf0ca9b332365768f1 to your computer and use it in GitHub Desktop.
Save slmjkdbtl/edfd41b6e828bedf0ca9b332365768f1 to your computer and use it in GitHub Desktop.
basic audio streaming
// macOS
// CFLAGS += -ObjC
// LDFLAGS += -framework Cocoa -framework OpenGL -framework AudioToolbox
#define GL_SILENCE_DEPRECATION 1
#import <Cocoa/Cocoa.h>
#include <OpenGL/gl.h>
#include <AudioToolbox/AudioToolbox.h>
#define BUFFER_FRAMES 1024
#define SAMPLE_RATE 44100
#define NUM_CHANNELS 1
int t = 0;
int freq = 440;
float volume = 0.3;
static void stream_audio(void *udata, AudioQueueRef queue, AudioQueueBufferRef buffer) {
int num_frames = buffer->mAudioDataByteSize / (sizeof(float) * NUM_CHANNELS);
float *data = (float*)buffer->mAudioData;
for (int i = 0; i < num_frames; i++) {
t++;
data[i] = sin((float)t / SAMPLE_RATE * freq * 2.0 * 3.14) * volume;
}
AudioQueueEnqueueBuffer(queue, buffer, 0, NULL);
}
int main() {
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp activateIgnoringOtherApps:YES];
NSWindow *window = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0, 0, 400, 400)
styleMask:
0
| NSWindowStyleMaskTitled
| NSWindowStyleMaskClosable
| NSWindowStyleMaskResizable
| NSWindowStyleMaskMiniaturizable
backing:NSBackingStoreBuffered
defer:NO
];
NSOpenGLView *view = [[NSOpenGLView alloc] init];
[window setContentView:view];
[window makeFirstResponder:view];
[window setTitle:@"hi"];
[window center];
[window makeKeyAndOrderFront:nil];
NSOpenGLContext *ctx = [view openGLContext];
[ctx makeCurrentContext];
AudioStreamBasicDescription fmt = {
.mSampleRate = SAMPLE_RATE,
.mFormatID = kAudioFormatLinearPCM,
.mFormatFlags = 0
| kLinearPCMFormatFlagIsFloat
| kAudioFormatFlagIsPacked
,
.mFramesPerPacket = 1,
.mChannelsPerFrame = NUM_CHANNELS,
.mBytesPerFrame = sizeof(float) * NUM_CHANNELS,
.mBytesPerPacket = sizeof(float) * NUM_CHANNELS,
.mBitsPerChannel = 32,
};
AudioQueueRef queue;
AudioQueueNewOutput(
&fmt,
stream_audio,
NULL,
NULL,
NULL,
0,
&queue
);
for (int i = 0; i < 2; i++) {
int buf_size = BUFFER_FRAMES * fmt.mBytesPerFrame;
AudioQueueBufferRef buf;
AudioQueueAllocateBuffer(queue, buf_size, &buf);
buf->mAudioDataByteSize = buf_size;
memset(buf->mAudioData, 0, buf->mAudioDataByteSize);
AudioQueueEnqueueBuffer(queue, buf, 0, NULL);
}
AudioQueueStart(queue, NULL);
while (1) {
while (1) {
NSEvent *event = [NSApp
nextEventMatchingMask:NSEventMaskAny
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES
];
if (event == nil) {
break;
}
switch (event.type) {
case NSEventTypeKeyDown:
break;
default:
break;
}
[NSApp sendEvent:event];
}
NSPoint mpos = [window mouseLocationOutsideOfEventStream];
if (mpos.x > 200.0 && mpos.x < 400.0) {
freq = (int)mpos.x * 2;
}
glClearColor(0, mpos.x / 400, mpos.y / 400, 1);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment