Last active
August 9, 2023 17:23
-
-
Save velzie/874e02cb9cb0920b644856dfbd8dd049 to your computer and use it in GitHub Desktop.
linux pcspkr rickroll in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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