1 #define _POSIX_C_SOURCE 200809L
7 #include <sys/soundcard.h>
21 /* Stupid declarations */
23 #define BIT_RATE 48000
25 typedef int16_t sample_t
;
26 #define SAMPLE_MIN -32768
27 #define SAMPLE_MAX 32767
29 typedef void(*synth_t
)(uint_least16_t freq
, sample_t
*buf
, size_t count
);
33 uint_least16_t note(int_least8_t X
) {
34 return 440 * pow(2, X
/ 12.0);
39 void void_synth(uint_least16_t freq
, sample_t
*buf
, size_t count
) {
40 memset(buf
, 0, count
* sizeof(sample_t
));
43 void square_synth(uint_least16_t freq
, sample_t
*buf
, size_t count
) {
44 sample_t a
= SAMPLE_MAX
;
45 uint_least16_t period
= BIT_RATE
/ freq
;
47 for (size_t i
= 0; i
< count
; i
++) {
48 if (!(i
%period
)) a
= (a
== SAMPLE_MAX
) ? SAMPLE_MIN
: SAMPLE_MAX
;
53 /* Signal manipulating tools */
55 void attenuate(sample_t
*track
, size_t len
, double level
) {
56 for (size_t i
= 0; i
< len
; i
++) {
61 void mix(sample_t
*dest
, sample_t
*src
, size_t len
) {
62 for (size_t i
= 0; i
< len
; i
++) {
69 void play(sample_t
*what
, size_t len
) {
70 write(F
, what
, len
* sizeof(sample_t
));
73 void show(sample_t
*what
, size_t len
) {
74 for (size_t i
= 0; i
< len
; i
++) {
75 printf("%hd ", what
[i
]);
81 F
= open("/dev/dsp", O_WRONLY
);
83 error(1, errno
, NULL
);
87 ioctl(F
, SNDCTL_DSP_CHANNELS
, &i
);
89 ioctl(F
, SNDCTL_DSP_SETFMT
, &i
);
91 ioctl(F
, SNDCTL_DSP_SPEED
, &i
);
94 void interpret_track(char *instr
, size_t instrlen
, char *what
, uint_least16_t *off
, int_least16_t size
) {
97 sample_t
*b1
= malloc(size
* sizeof(sample_t
));
99 for (size_t len
= strchr(what
+ *off
, '\n') - what
; *off
< len
; (*off
)++) {
101 void_synth(0, b1
, size
);
103 if (strncmp(instr
, "square", labellen
) == 0) {
104 square_synth(note((what
[off
] - 'e') * 2), b1
, size
);
109 uint_least8_t track = strtol(label, &fail, 10);
110 assert(fail != label);
119 void interpret(char *what
, size_t len
, int_least16_t size
) {
120 uint_least16_t off
= 0;
121 sample_t
*b1
= malloc(size
* sizeof(sample_t
));
125 //if (size > ) { /* size is per note */
126 //} else { /* size is per code chunk */
138 if (off
== 0 || what
[off
- 1] == '\n') {
139 if (n
== '>') { // define the subroutine
141 } else if (n
== '<') { // use the subroutine
142 label
= what
+ off
+ 1;
143 labellen
= strchr(label
, '>') - label
;
157 int songf
= open("song", O_RDONLY
);
159 char *song
, *songfile
;
160 //size_t chunk = BIT_RATE * 0.04;
165 songlen
= lseek(songf
, 0, SEEK_END
);
167 lseek(songf
, 0, SEEK_SET
);
168 songfile
= mmap(NULL
, songlen
, PROT_READ
, MAP_SHARED
, songf
, 0);
169 assert(songfile
!= MAP_FAILED
);
172 sscanf(songfile
, "%lf", ¬elength
);
173 printf("Notelength: %lf\n", notelength
);
174 assert(notelength
> 0);
175 size_t notelen
= notelength
* BIT_RATE
; // :]
177 song
= strchr(songfile
, '\n') + 1;
181 b1
= malloc(notelen
* sizeof(sample_t
));
185 char *programs
[16] = {0};
187 interpret(song
, songlen
, notelen
);