You are not logged in.
C code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
typedef struct {
int freq;
int length;
} Note;
int play_note(int fd, Note note) {
if (note.freq > 0) {
if (ioctl(fd, KIOCSOUND, 1193180 / note.freq) < 0) {
perror("ioctl: KIOCSOUND (Sound on)");
return -1;
}
}
usleep(note.length * 1000);
if (ioctl(fd, KIOCSOUND, 0) < 0) {
perror("ioctl: KIOCSOUND (Sound off)");
return -1;
}
return 0;
}
int main() {
int fd;
Note melody[] = {
{784, 500}, {784, 500}, {784, 500}, {622, 350}, {830, 150},
{784, 500}, {622, 350}, {830, 150}, {784, 1000}, {1244, 500},
{1244, 500}, {1244, 500}, {1318, 350}, {1046, 150}, {830, 500},
{622, 350}, {830, 150}, {784, 1000}, {1568, 500}, {784, 350},
{784, 150}, {1568, 500}, {1480, 250}, {1396, 250}, {1318, 125},
{1244, 125}, {1318, 250}, {831, 250}, {1046, 500}, {988, 250},
{932, 250}, {880, 125}, {831, 125}, {880, 250}, {622, 125},
{784, 500}, {622, 375}, {784, 125}, {880, 500}, {784, 375},
{880, 125}, {1046, 1000}
};
int melody_length = sizeof(melody) / sizeof(melody[0]);
fd = open("/dev/console", O_WRONLY);
if (fd == -1) {
fd = open("/dev/tty0", O_WRONLY);
if (fd == -1) {
perror("Error opening console device");
return 1;
}
}
printf("Darth Vader appears...\n");
for (int i = 0; i < melody_length; i++) {
if (play_note(fd, melody[i]) < 0) {
close(fd);
return 1;
}
usleep(50 * 1000);
}
printf("And disappears again!\n");
close(fd);
return 0;
}
Save as 'darthvader.c' for example
compile:
gcc darthvader.c -o darthvader
Program must be run as root
sudo ./darthvader
or you set the 's' bit:
sudo chown root:root darthvader
sudo chmod u+s darthvader
./darthvader
enjoy!
Last edited by EISENFELD (2025-04-01 02:57:28)
Ich weiß, dass ich nichts weiß !
Offline
...
Program must be run as root
...
or you set the 's' bit:
this is not a good idea. I suggest you find out, how to run as normal user.
Offline
Direct access to the hardware always needs root privileges in C. You could add the program to a group 'audio' for example which has the needed privileges or something like that. I didn't find an easy solution for that.
Ich weiß, dass ich nichts weiß !
Offline
https://en.wikipedia.org/wiki/The_Imperial_March
The imperial march is set in g-minor, 440Hz is a¹ and has no business being there.
(The theme is later on referenced in a-minor during the lighthearted busy phase but then returns in full force to g-minor and that's what you think of when you see Vader)
Also, if you've pcspkr blacklisted as normal humans
mpv -vo null 'https://www.youtube.com/watch?v=UOEaZOHyo6w'
Offline
Yes, you are absolutely right, it must be g-minor. Thanks.
This should sound a bit better (it's still not perfect)
Note melody[] = {
{784, 500}, {784, 500}, {784, 500}, {622, 350}, {830, 150},
{784, 500}, {622, 350}, {830, 150}, {784, 1000}, {1244, 500},
{1244, 500}, {1244, 500}, {1318, 350}, {1046, 150}, {830, 500},
{622, 350}, {830, 150}, {784, 1000}, {1568, 500}, {784, 350},
{784, 150}, {1568, 500}, {1480, 250}, {1396, 250}, {1318, 125},
{1244, 125}, {1318, 250}, {831, 250}, {1046, 500}, {988, 250},
{932, 250}, {880, 125}, {831, 125}, {880, 250}, {622, 125},
{784, 500}, {622, 375}, {784, 125}, {880, 500}, {784, 375},
{880, 125}, {1046, 1000}
};
May the force be with you
Ich weiß, dass ich nichts weiß !
Offline
Now, I found a way to play speaker sound without root privileges in C: (It should work on Arch out of the box, "libevdev" package is needed)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <libevdev-1.0/libevdev/libevdev.h>
typedef struct {
int frequency;
int duration;
int delay;
} Note;
void play_tone(int fd, int freq, int duration_ms) {
struct input_event event;
event.type = EV_SND;
event.code = SND_TONE;
event.value = freq;
write(fd, &event, sizeof(event));
usleep(duration_ms * 1000);
event.value = 0;
write(fd, &event, sizeof(event));
}
int main() {
int fd = open("/dev/input/by-path/platform-pcspkr-event-spkr", O_WRONLY);
if (fd == -1) {
perror("Error opening PC Speaker device!");
return 1;
}
// Converted notes from GH user "Josef-Friedrich" and his "beep-melodies" repo. Thanks!
Note melody[] = {
{392, 350, 100}, {392, 350, 100}, {392, 350, 100}, {311, 250, 100},
{466, 25, 100}, {392, 350, 100}, {311, 250, 100}, {466, 25, 100},
{392, 700, 100}, {587, 350, 100}, {587, 350, 100}, {587, 350, 100},
{622, 250, 100}, {466, 25, 100}, {370, 350, 100}, {311, 250, 100},
{466, 25, 100}, {392, 700, 100}, {784, 350, 100}, {392, 250, 100},
{392, 25, 100}, {784, 350, 100}, {740, 250, 100}, {698, 25, 100},
{659, 25, 100}, {622, 25, 100}, {659, 50, 400}, {415, 25, 200},
{554, 350, 100}, {523, 250, 100}, {494, 25, 100}, {466, 25, 100},
{440, 25, 100}, {466, 50, 400}, {311, 25, 200}, {370, 350, 100},
{311, 250, 100}, {392, 25, 100}, {466, 350, 100}, {392, 250, 100},
{466, 25, 100}, {587, 700, 100}, {784, 350, 100}, {392, 250, 100},
{392, 25, 100}, {784, 350, 100}, {740, 250, 100}, {698, 25, 100},
{659, 25, 100}, {622, 25, 100}, {659, 50, 400}, {415, 25, 200},
{554, 350, 100}, {523, 250, 100}, {494, 25, 100}, {466, 25, 100},
{440, 25, 100}, {466, 50, 400}, {311, 25, 200}, {392, 350, 100},
{311, 250, 100}, {466, 25, 100}, {392, 300, 150}, {311, 250, 100},
{466, 25, 100}, {392, 700, 0}
};
int notes = sizeof(melody) / sizeof(melody[0]);
for (int i = 0; i < notes; i++) {
play_tone(fd, melody[i].frequency, melody[i].duration);
usleep(melody[i].delay * 1000);
}
close(fd);
return 0;
}
compile:
gcc darthvader.c -o darthvader
run:
./darthvader
Ich weiß, dass ich nichts weiß !
Offline