Skip to content

Instantly share code, notes, and snippets.

@J3698
Last active April 29, 2019 01:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save J3698/ecbdcda0531d0186a044b9c147a9e6e4 to your computer and use it in GitHub Desktop.
Save J3698/ecbdcda0531d0186a044b9c147a9e6e4 to your computer and use it in GitHub Desktop.
A very simple visualizer
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <getopt.h>
#include <string.h>
#include <wchar.h>
#include <locale.h>
#include <jack/jack.h>
#include <jack/transport.h>
// the datatype for audio (should be a double)
typedef jack_default_audio_sample_t sample_t;
// the name of this program
char *client_name = "Visualizer";
// what client that interacts with jack
jack_client_t *client;
// ports for left and right audio sent to speaker
jack_port_t *output_port_l;
jack_port_t *output_port_r;
// ports for left and right audio coming from system (e.g. a connected phone)
jack_port_t *input_port_l;
jack_port_t *input_port_r;
/* this method does all of the processing and heavylifting in the program.
* In this case, it just routes input data to output data, and prints 1s
* if a chunk of audio is above a certain volume, and 0s if it is not.
*/
int process(jack_nframes_t nframes, void *arg) {
sample_t *outBufferLeft = (sample_t *) jack_port_get_buffer(output_port_l, nframes);
sample_t *outBufferRight = (sample_t *) jack_port_get_buffer(output_port_r, nframes);
sample_t *inBufferLeft = (sample_t *) jack_port_get_buffer(input_port_l, nframes);
sample_t *inBufferRight = (sample_t *) jack_port_get_buffer(input_port_r, nframes);
// copy input audio to output
memcpy(outBufferLeft, inBufferLeft, sizeof(sample_t) * nframes);
memcpy(outBufferRight, inBufferRight, sizeof(sample_t) * nframes);
// calculate an estimate for the volume of the data
double total = 0;
for (int i = 0; i < nframes; i++) {
total += pow(outBufferLeft[i], 2);
total += pow(outBufferRight[i], 2);
}
// print to the console based on the volume estimate
if (total > 0.3) {
printf("\n111111111111111111");
} else {
printf("\n000000000000000000");
}
// uncomment the following line for debugging
// printf("%f\n", total);
return 0;
}
// boilerplate code to start a connection to jack
bool startClient() {
jack_status_t status;
while ((client = jack_client_open(client_name, 0, &status)) == 0) {
fprintf(stderr, "jack server not running?\n");
return false;
}
printf("Client started\n");
return true;
}
// create ports in order to read and write audio data (possibly extraneous)
void createPorts() {
output_port_l = jack_port_register(client, "lag_out_l", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
output_port_r = jack_port_register(client, "lag_out_r", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
input_port_l = jack_port_register(client, "lag_in_l", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
input_port_r = jack_port_register(client, "lag_in_r", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
printf("Ports created\n");
}
// connect ports from the system and the speakers to our ports
void connectPorts() {
jack_connect(client, "PulseAudio JACK Sink:front-left", jack_port_name(input_port_l));
jack_connect(client, "PulseAudio JACK Sink:front-right", jack_port_name(input_port_r));
jack_connect(client, jack_port_name(output_port_l), "system:playback_1");
jack_connect(client, jack_port_name(output_port_r), "system:playback_2");
printf("Ports connected\n");
}
/**
* In the main method jack gets started, ports get created and connected,
* and jack is told to call the process function when more work is to be done.
* A list of port names is also printed, for debugging purposes.
*/
int main(int argc, char *argv[]) {
if (!startClient()) {
return -1;
}
createPorts();
jack_set_process_callback(client, process, 0);
if (jack_activate(client)) {
fprintf(stderr, "cannot activate client");
return 1;
}
printf("Jack activated\n");
connectPorts();
const char **port_names = jack_get_ports(client, NULL, NULL, 0);
for (int j = 0; port_names[j] != NULL; j++) {
printf("%s\n", port_names[j]);
}
while (true) {
sleep(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment