From 00e6a8a5a32222d65df85005dc404988f9430bc7 Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Thu, 16 Nov 2023 19:14:34 +0100 Subject: Makefile + PaClose --- .gitignore | 4 +- Makefile | 31 ++++++++++++ main.c | 153 ---------------------------------------------------------- src/main.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+), 154 deletions(-) create mode 100644 Makefile delete mode 100644 main.c create mode 100644 src/main.c diff --git a/.gitignore b/.gitignore index cba7efc..2301d9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -a.out +gtk-dav +*.d +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1a0c98d --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +CXX=g++ +CC=gcc + +LDFLAGS=-lportaudio $(shell pkg-config --libs gtk4 cairo) +CXXFLAGS=-Wall $(shell pkg-config --cflags gtk4 cairo) -O3 -MD -MP +OBJS=\ + src/main.o + +.PHONY: all build run clean + +all: gtk-dav + +gtk-dav: ./Makefile $(OBJS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) -o ./gtk-dav + +%.o: %.c + $(CC) $(CXXFLAGS) -c $< -o $@ + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +run: ./gtk-dav + @./gtk-dav + +clean: + @find -name "*.o" -exec rm {} \; + @find -name "*.d" -exec rm {} \; + @rm -f ./gtk-dav + + +-include $(OBJECTS:.o=.d) diff --git a/main.c b/main.c deleted file mode 100644 index 64bceaa..0000000 --- a/main.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include -#include - -int device = -1; - -typedef struct { - float left; - float right; -} AudioData; - -AudioData audiodata; - -struct data { - int device_num; -}; - -PaStream *stream = NULL; -GtkWidget *drawing_area; - -#define FRAMES_PER_BUFFER 256 - -int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) -{ - AudioData *data = (AudioData *)userData; - float *in = (float *)inputBuffer; - - if (data->left > 0) { - data->left -= 0.005; - } - - if (data->right > 0) { - data->right -= 0.005; - } - - for (unsigned long i = 0; i < framesPerBuffer * 2; i += 2) { - data->left = MAX(data->left, fabs(in[i])); - data->right = MAX(data->right, fabs(in[i + 1])); - } - - if (drawing_area) { - gtk_widget_queue_draw(GTK_WIDGET(drawing_area)); - } - - return 0; -} - -static void select_device(GtkWidget *widget, gpointer data) -{ - struct data *d = (struct data *)data; - device = d->device_num; - printf("Device %d selected\n", d->device_num); - - PaStreamParameters inputParameters; - memset(&inputParameters, 0, sizeof(inputParameters)); - inputParameters.channelCount = 2; - inputParameters.device = device; - inputParameters.hostApiSpecificStreamInfo = NULL; - inputParameters.sampleFormat = paFloat32; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(device)->defaultLowInputLatency; - - Pa_OpenStream(&stream, &inputParameters, NULL, Pa_GetDeviceInfo(device)->defaultSampleRate, FRAMES_PER_BUFFER, paNoFlag, patestCallback, &audiodata); - Pa_StartStream(stream); -} - -static void draw(cairo_t *cr, GtkWidget *area) -{ - cairo_set_source_rgba(cr, 1, 0, 0, 1); - cairo_arc(cr, 250, 250, audiodata.left * 250, 0, 2 * M_PI); - cairo_arc(cr, 800, 250, audiodata.right * 250, 0, 2 * M_PI); - cairo_fill(cr); - - gtk_widget_queue_draw(area); -} - -static void draw_cb(GtkDrawingArea *drawing_area, cairo_t *cr, int width, int height, gpointer data) -{ - cairo_paint(cr); - draw(cr, data); -} - -static void refresh() -{ -} - -static void activate(GtkApplication *app, gpointer user_data) -{ - GtkWidget *window; - GtkWidget *grid; - GtkWidget *button; - - // init window - window = gtk_application_window_new(app); - gtk_window_set_title(GTK_WINDOW(window), "Directional Audio Visualizer"); - - // init grid - grid = gtk_grid_new(); - gtk_window_set_child(GTK_WINDOW(window), grid); - - // init drawing_area - drawing_area = gtk_drawing_area_new(); - gtk_widget_set_size_request(drawing_area, 1050, 500); - gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(drawing_area), draw_cb, drawing_area, NULL); - gtk_grid_attach(GTK_GRID(grid), drawing_area, 1, 2, 100, 100); - - // init audio devices - Pa_Initialize(); - int numDevices = Pa_GetDeviceCount(); - - if (numDevices < 0) { - printf("Error getting device count.\n"); - exit(EXIT_FAILURE); - } else if (numDevices == 0) { - printf("There are no available audio devices on this machine.\n"); - exit(EXIT_SUCCESS); - } - - // init button for every audio device - for (int i = 0; i < numDevices; i++) { - const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(i); - struct data *d = malloc(sizeof(struct data)); - d->device_num = i; - button = gtk_button_new_with_label(deviceInfo->name); - g_signal_connect(button, "clicked", G_CALLBACK(select_device), d); - gtk_grid_attach(GTK_GRID(grid), button, 0, numDevices - i - 1, 1, 1); - } - - // init button for refresh - button = gtk_button_new_with_label("Refresh"); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(refresh), window); - gtk_grid_attach(GTK_GRID(grid), button, 1, 0, 1, 1); - - // init button for quit - button = gtk_button_new_with_label("Quit"); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_destroy), window); - gtk_grid_attach(GTK_GRID(grid), button, 1, 1, 1, 1); - - // set window - gtk_window_present(GTK_WINDOW(window)); -} - -int main(int argc, char **argv) -{ - GtkApplication *app; - int status; - - app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS); - g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); - status = g_application_run(G_APPLICATION(app), argc, argv); - g_object_unref(app); - - return status; -} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e5b7988 --- /dev/null +++ b/src/main.c @@ -0,0 +1,159 @@ +#include +#include +#include + +int device = -1; + +typedef struct { + float left; + float right; +} AudioData; + +AudioData audiodata; + +struct data { + int device_num; +}; + +PaStream *stream = NULL; +GtkWidget *drawing_area; + +#define FRAMES_PER_BUFFER 256 + +int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) +{ + AudioData *data = (AudioData *)userData; + float *in = (float *)inputBuffer; + + if (data->left > 0) { + data->left -= 0.005; + } + + if (data->right > 0) { + data->right -= 0.005; + } + + for (unsigned long i = 0; i < framesPerBuffer * 2; i += 2) { + data->left = MAX(data->left, fabs(in[i])); + data->right = MAX(data->right, fabs(in[i + 1])); + } + + if (drawing_area) { + gtk_widget_queue_draw(GTK_WIDGET(drawing_area)); + } + + return 0; +} + +static void select_device(GtkWidget *widget, gpointer data) +{ + if (stream != NULL) { + Pa_StopStream(stream); + Pa_CloseStream(stream); + stream = NULL; + } + + struct data *d = (struct data *)data; + device = d->device_num; + printf("Device %d selected\n", d->device_num); + + PaStreamParameters inputParameters; + memset(&inputParameters, 0, sizeof(inputParameters)); + inputParameters.channelCount = 2; + inputParameters.device = device; + inputParameters.hostApiSpecificStreamInfo = NULL; + inputParameters.sampleFormat = paFloat32; + inputParameters.suggestedLatency = Pa_GetDeviceInfo(device)->defaultLowInputLatency; + + Pa_OpenStream(&stream, &inputParameters, NULL, Pa_GetDeviceInfo(device)->defaultSampleRate, FRAMES_PER_BUFFER, paNoFlag, patestCallback, &audiodata); + Pa_StartStream(stream); +} + +static void draw(cairo_t *cr, GtkWidget *area) +{ + cairo_set_source_rgba(cr, 1, 0, 0, 1); + cairo_arc(cr, 250, 250, audiodata.left * 250, 0, 2 * M_PI); + cairo_arc(cr, 800, 250, audiodata.right * 250, 0, 2 * M_PI); + cairo_fill(cr); + + gtk_widget_queue_draw(area); +} + +static void draw_cb(GtkDrawingArea *drawing_area, cairo_t *cr, int width, int height, gpointer data) +{ + cairo_paint(cr); + draw(cr, data); +} + +static void refresh() +{ +} + +static void activate(GtkApplication *app, gpointer user_data) +{ + GtkWidget *window; + GtkWidget *grid; + GtkWidget *button; + + // init window + window = gtk_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(window), "Directional Audio Visualizer"); + + // init grid + grid = gtk_grid_new(); + gtk_window_set_child(GTK_WINDOW(window), grid); + + // init drawing_area + drawing_area = gtk_drawing_area_new(); + gtk_widget_set_size_request(drawing_area, 1050, 500); + gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(drawing_area), draw_cb, drawing_area, NULL); + gtk_grid_attach(GTK_GRID(grid), drawing_area, 1, 2, 100, 100); + + // init audio devices + Pa_Initialize(); + int numDevices = Pa_GetDeviceCount(); + + if (numDevices < 0) { + printf("Error getting device count.\n"); + exit(EXIT_FAILURE); + } else if (numDevices == 0) { + printf("There are no available audio devices on this machine.\n"); + exit(EXIT_SUCCESS); + } + + // init button for every audio device + for (int i = 0; i < numDevices; i++) { + const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo(i); + struct data *d = malloc(sizeof(struct data)); + d->device_num = i; + button = gtk_button_new_with_label(deviceInfo->name); + g_signal_connect(button, "clicked", G_CALLBACK(select_device), d); + gtk_grid_attach(GTK_GRID(grid), button, 0, numDevices - i - 1, 1, 1); + } + + // init button for refresh + button = gtk_button_new_with_label("Refresh"); + g_signal_connect_swapped(button, "clicked", G_CALLBACK(refresh), window); + gtk_grid_attach(GTK_GRID(grid), button, 1, 0, 1, 1); + + // init button for quit + button = gtk_button_new_with_label("Quit"); + g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_destroy), window); + gtk_grid_attach(GTK_GRID(grid), button, 1, 1, 1, 1); + + // set window + gtk_window_present(GTK_WINDOW(window)); +} + +int main(int argc, char **argv) +{ + GtkApplication *app; + int status; + + app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + + return status; +} -- cgit v1.2.3