-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsndgraph.cpp
More file actions
148 lines (119 loc) · 4.06 KB
/
sndgraph.cpp
File metadata and controls
148 lines (119 loc) · 4.06 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* @file sndgraph.cpp
* Main file for the sngraph app.
*
* @author Gašper Ažman (GA), gasper.azman@gmail.com
* @version 1.0
* @since 2010-06-03 03:50:57 PM
*/
#include "player.hpp"
#include "composition.hpp"
#include <SDL/SDL.h>
#include <SDL/SDL_audio.h>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
using namespace sgr;
using namespace std;
double dist(double in) {
double sign = (in > 0)? 1 : -1;
in *= sign;
return sign * (3.08095 * in - 2.38095 * in * in);
// return sign * (2.08095 * in - 1.38095 * in * in);
}
void audio_callback(void *userdata, Uint8 *stream_in, int len_in);
struct callback_data {
sgr::player::player track;
SDL_AudioSpec fmt;
vector<scalars::sample> sound;
callback_data(sgr::player::player track, size_t samples)
: track(track)
, fmt()
, sound()
{
fmt.callback = audio_callback;
fmt.channels = 2;
fmt.format = AUDIO_S16;
fmt.samples = 2*samples;
fmt.freq = 44100;
fmt.userdata = this;
SDL_AudioSpec got_fmt;
SDL_OpenAudio(&fmt, &got_fmt);
fmt = got_fmt;
sound.resize(fmt.samples);
}
};
void fmtdataToStream(
const callback_data& data,
Uint8 *stream,
size_t stream_len
)
{
size_t end = data.sound.size();
for (size_t i = 0; (i < end) && (2*i+1 < stream_len); ++i) {
int16_t right = data.sound[i].right * 0x7FFF;
int16_t left = data.sound[i].left * 0x7FFF;
reinterpret_cast<int16_t*>(stream)[i*2] = left;
reinterpret_cast<int16_t*>(stream)[i*2+1] = right;
}
}
void audio_callback(void *userdata, Uint8 *stream_in, int len_in) {
if (userdata == NULL) { return; }
callback_data &fmt_data = *static_cast<callback_data*>(userdata);
// cast frequency from int to double
units::frequency samples_per_sec{static_cast<double>(fmt_data.fmt.freq)};
units::time dt_per_tick{1/samples_per_sec.value};
size_t end = fmt_data.sound.size();
for (size_t tick = 0; tick < end; ++tick) {
fmt_data.track.advance(dt_per_tick);
fmt_data.sound[tick] = fmt_data.track.sound();
}
fmtdataToStream(fmt_data, stream_in, len_in);
}
int main( int /* argc */, char ** /* argv */ )
{
using namespace sgr::notation;
namespace sc = scalars;
try {
sgr::notation::song song;
sgr::composition::resources stuff;
song << timing::linear::create(units::beat{200}, units::bps{1}, units::bps{10});
song << timing::constant::create(units::beat{128}, units::bps{1});
for (size_t i = 0; i < 20; i+=1) {
song << note(
instrument::sawwave::create(),
volume::simple::create(sc::volume{1,1}),
pitch::constant::create(units::tone{-26}),
hit(units::beat{double(i*8)}, units::beat{4}, 1));
song << note(
instrument::sinewave::create(),
volume::simple::create(sc::volume{0.7,0.7}),
pitch::constant::create(units::tone{-4}),
hit(units::beat{double(i*8+4)}, units::beat{4}, 1));
}
// for (size_t i = 0; i < 200; i+=4) {
// song << note(
// instrument::sinewave::create(),
// volume::simple::create(0.3,0.3),
// pitch::constant::create(0),
// hit(i,2,1)
// )
// << note(
// instrument::sinewave::create(),
// volume::simple::create(0.3,0.3),
// pitch::constant::create(-3),
// hit(i+2,2,1)
// );
// }
callback_data data( sgr::player::player(song), 512);
std::cout << "channels: " << (int) data.fmt.channels << " samples: " <<
data.fmt.samples << " freq: " << data.fmt.freq << std::endl;
SDL_PauseAudio(0);
while (true) {
usleep(1600);
}
} catch ( boost::exception& e) {
std::cerr << boost::diagnostic_information(e);
}
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */