Skip to content

Instantly share code, notes, and snippets.

@velzie
Last active August 9, 2023 17:23
Show Gist options
  • Save velzie/874e02cb9cb0920b644856dfbd8dd049 to your computer and use it in GitHub Desktop.
Save velzie/874e02cb9cb0920b644856dfbd8dd049 to your computer and use it in GitHub Desktop.
linux pcspkr rickroll in C
/* compile:
```
gcc rickroll.c
sudo ./a.out
```
MUST BE RUN AS ROOT
*/
#include <fcntl.h> // open
#include <linux/input.h> // struct input_event
#include <linux/kd.h>
#include <math.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <time.h> // nanosleep
#include <unistd.h> // write, close
#include <unistd.h>
/*
https://create.arduino.cc/projecthub/410027/rickroll-piezo-buzzer-a1cd11
modified for a standard pc
*/
static char const *const default_device = "/dev/console";
#define a3f 208 // 208 Hz
#define b3f 233 // 233 Hz
#define b3 247 // 247 Hz
#define c4 261 // 261 Hz MIDDLE C
#define c4s 277 // 277 Hz
#define e4f 311 // 311 Hz
#define f4 349 // 349 Hz
#define a4f 415 // 415 Hz
#define b4f 466 // 466 Hz
#define b4 493 // 493 Hz
#define c5 523 // 523 Hz
#define c5s 554 // 554 Hz
#define e5f 622 // 622 Hz
#define f5 698 // 698 Hz
#define f5s 740 // 740 Hz
#define a5f 831 // 831 Hz
#define rest -1
#define CLOCK_TICK_RATE 1193180
volatile int beatlength = 100; // determines tempo
float beatseparationconstant = 0.3;
int threshold;
int a; // part index
int b; // song index
int c; // lyric index
bool flag;
// Parts 1 and 2 (Intro)
int song1_intro_melody[] = {c5s, e5f, e5f, f5, a5f, f5s, f5,
e5f, c5s, e5f, rest, a4f, a4f};
int song1_intro_rhythmn[] = {6, 10, 6, 6, 1, 1, 1, 1, 6, 10, 4, 2, 10};
// Parts 3 or 5 (Verse 1)
int song1_verse1_melody[] = {
rest, c4s, c4s, c4s, c4s, e4f, rest, c4, b3f, a3f, rest, b3f, b3f,
c4, c4s, a3f, a4f, a4f, e4f, rest, b3f, b3f, c4, c4s, b3f, c4s,
e4f, rest, c4, b3f, b3f, a3f, rest, b3f, b3f, c4, c4s, a3f, a3f,
e4f, e4f, e4f, f4, e4f, c4s, e4f, f4, c4s, e4f, e4f, e4f, f4,
e4f, a3f, rest, b3f, c4, c4s, a3f, rest, e4f, f4, e4f};
int song1_verse1_rhythmn[] = {2, 1, 1, 1, 1, 2, 1, 1, 1, 5, 1, 1, 1, 1, 3, 1,
2, 1, 5, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 3,
1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 3, 1, 1, 1, 3};
// Parts 4 or 6 (Chorus)
int song1_chorus_melody[] = {
b4f, b4f, a4f, a4f, f5, f5, e5f, b4f, b4f, a4f, a4f, e5f, e5f, c5s, c5,
b4f, c5s, c5s, c5s, c5s, c5s, e5f, c5, b4f, a4f, a4f, a4f, e5f, c5s, b4f,
b4f, a4f, a4f, f5, f5, e5f, b4f, b4f, a4f, a4f, a5f, c5, c5s, c5, b4f,
c5s, c5s, c5s, c5s, c5s, e5f, c5, b4f, a4f, rest, a4f, e5f, c5s, rest};
int song1_chorus_rhythmn[] = {1, 1, 1, 1, 3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1,
2, 1, 1, 1, 1, 3, 3, 3, 1, 2, 2, 2, 4, 8, 1,
1, 1, 1, 3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1, 3, 3, 3, 1, 2, 2, 2, 4, 8, 4};
void delay(unsigned int ms) {
struct timespec duration = {.tv_sec = ms / 1000U,
.tv_nsec = (long)(ms % 1000UL * 1000UL * 1000UL)};
nanosleep(&duration, NULL);
}
void start_beep(int fd, int freq) {
if (freq == 0) {
ioctl(fd, KIOCSOUND, 0);
} else {
ioctl(fd, KIOCSOUND, (int)(CLOCK_TICK_RATE / freq));
}
}
void tone(int fd, int freq, int duration) {
start_beep(fd, freq);
delay(duration);
start_beep(fd, 0);
}
void play(int piezo) {
int notelength;
if (a == 1 || a == 2) {
// intro
notelength = beatlength * song1_intro_rhythmn[b];
if (song1_intro_melody[b] > 0) {
tone(piezo, song1_intro_melody[b], notelength);
}
b++;
if (b >= sizeof(song1_intro_melody) / sizeof(int)) {
a++;
b = 0;
c = 0;
}
} else if (a == 3 || a == 5) {
// verse
notelength = beatlength * 2 * song1_verse1_rhythmn[b];
if (song1_verse1_melody[b] > 0) {
tone(piezo, song1_verse1_melody[b], notelength);
c++;
}
b++;
if (b >= sizeof(song1_verse1_melody) / sizeof(int)) {
a++;
b = 0;
c = 0;
}
} else if (a == 4 || a == 6) {
// chorus
notelength = beatlength * song1_chorus_rhythmn[b];
if (song1_chorus_melody[b] > 0) {
tone(piezo, song1_chorus_melody[b], notelength);
c++;
}
b++;
if (b >= sizeof(song1_chorus_melody) / sizeof(int)) {
a++;
b = 0;
c = 0;
}
}
delay(notelength);
delay(notelength * beatseparationconstant);
if (a == 7) { // loop back around to beginning of song
a = 1;
}
}
int main() {
int fd = open(default_device, O_WRONLY);
flag = true;
a = 4;
b = 0;
c = 0;
while (true) {
if (flag == true) {
play(fd);
}
}
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment