forked from Yuri213212/tetris
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sound.h
108 lines (96 loc) · 1.82 KB
/
sound.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef SOUND_H_
#define SOUND_H_
#define tempo 2205 //tempo=150bpm,speed=8x
const int note[12]={ //A-4=500Hz
442,468,496,525,557,590,
625,662,701,743,787,834,
};
#include "music.h"
int playing,qp,qc,phase,freq,rowcount,currentrow;
LARGE_INTEGER onesecond;
char pending[BufferLength];
LARGE_INTEGER time[BufferLength];
void sound_init(){
QueryPerformanceFrequency(&onesecond);
playing=ST_init;
qp=0;
qc=0;
phase=0;
freq=0;
rowcount=0;
currentrow=-1;
}
void sound_event(int type){
QueryPerformanceCounter(&time[qp]);
pending[qp]=type;
qp=(qp+1)%BufferLength;
}
double render(int start,int end){
double fs,fe;
if (start&0x80000){
fs=-1.0;
}else{
fs=0.0;
}
if (end&0x80000){
fe=-1.0;
}else{
fe=0.0;
}
if (fs==fe){
return fs;
}
if (start&0x80000){
return (double)(0x100000-(start&0xFFFFF))/(start-end);
}else{
return (double)((end&0xFFFFF)-0x80000)/(start-end);
}
}
void FillBuffer(short *buffer){
int n,cdata;
LARGE_INTEGER wallclock;
LONGLONG current;
QueryPerformanceCounter(&wallclock);
for (n=0;n<BufferLength;++n){
if (qc!=qp){
current=wallclock.QuadPart+onesecond.QuadPart*(n-BufferLength)/SampleRate;
while (qc!=qp){
if (current<time[qc].QuadPart) break;
if (pending[qc]>=playing){
playing=pending[qc];
rowcount=0;
currentrow=-1;
phase=0;
}
qc=(qc+1)%BufferLength;
}
}
if (playing>=0){
if (rowcount/tempo!=currentrow){
++currentrow;
cdata=music[playing][currentrow];
switch (cdata&0x0F){
case 0x0F:
break;
case 0x0E:
case 0x0D:
freq=0;
break;
case 0x0C:
freq=0;
phase=0;
playing=ST_dummy;
break;
default:
freq=note[cdata&0x0F]<<(cdata>>4);
break;
}
}
++rowcount;
}
cdata=phase;
phase+=freq;
buffer[n]=(short)render(cdata,phase)*(vol<<7);
}
}
#endif