Skip to content

Instantly share code, notes, and snippets.

@xsbee
Last active December 6, 2022 02:17
Show Gist options
  • Save xsbee/ff16ae528b24aa38c8d4c52bfedcedd4 to your computer and use it in GitHub Desktop.
Save xsbee/ff16ae528b24aa38c8d4c52bfedcedd4 to your computer and use it in GitHub Desktop.
Sweeping surface of frequency and amplitudes
/*
* sine.c
*
* Copyright 2022 xsbee <xyesbee@proton.me>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
#include <math.h>
#include "SDL.h"
#define M_TAU (2 * M_PI)
struct context {
/// Frequency of the wave.
float f;
/// Amplitude of the wave.
float A;
/// Phase offset it left at last callback.
float p;
/// Phase step
float s;
};
void sine(void *userdata, Uint8* stream, int len) {
struct context *c = userdata;
float *x = (float*) stream;
int N = len / sizeof(float);
float A = c->A;
float f = c->f;
float p = c->p;
float s = c->s;
for (int i = 0; i < N; ++i)
{
x[i] = A * sinf(M_TAU * f * p);
p += s;
}
c->p = fmod(p, M_TAU);
}
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
SDL_AudioDeviceID dev = 0;
SDL_AudioSpec want, have;
SDL_Event evt;
SDL_Window *win = NULL;
struct context *c = malloc(sizeof(struct context));
c->p = 0;
c->A = 1.0f;
c->f = 440.0f;
SDL_memset(&want, 0, sizeof(SDL_AudioSpec));
want.freq = 48000;
want.samples = 512;
want.format = AUDIO_F32SYS;
want.channels = 1;
want.callback = sine;
want.userdata = c;
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have,
SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
if (!dev) {
fprintf(stderr, "SDL_OpenAudioDevice(): %s\n", SDL_GetError());
goto end;
}
c->s = 1.0f / (float)have.freq;
win = SDL_CreateWindow("sine", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
800, 600,
SDL_WINDOW_MAXIMIZED |
SDL_WINDOW_RESIZABLE);
if (!win) {
fprintf(stderr, "SDL_CreateWindow(): %s\n", SDL_GetError());
goto end;
}
SDL_PauseAudioDevice(dev, 0);
float w, h;
for (; SDL_WaitEvent(&evt); ) {
switch (evt.type) {
case SDL_QUIT:
goto end;
case SDL_WINDOWEVENT:
if (evt.window.event == SDL_WINDOWEVENT_RESIZED) {
w = evt.window.data1;
h = evt.window.data2;
}
break;
case SDL_MOUSEMOTION:
c->f = (float)evt.motion.x / w * 2000.0f;
c->A = 1.0f - (float)evt.motion.y / h;
break;
}
}
end:
if (win)
SDL_DestroyWindow(win);
if (dev > 0)
SDL_CloseAudioDevice(dev);
if (c)
free(c);
SDL_Quit();
}
@xsbee
Copy link
Author

xsbee commented Dec 5, 2022

To compile run

gcc -Ofast -o sine sine.c `pkg-config sdl2 --cflags --libs`

// TODO make transitions more smoother with interpolation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment