-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstreams.cpp
More file actions
executable file
·118 lines (100 loc) · 3.47 KB
/
streams.cpp
File metadata and controls
executable file
·118 lines (100 loc) · 3.47 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
/*
ReSonat - soft-def players react in real-time to looped echoes of sound input
by playing notes through MIDI soft-synth to sound output.
https://github.com/sunkware/resonat
Copyright (c) 2024-2025 Sunkware
https://sunkware.org
ReSonat is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ReSonat is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ReSonat. If not, see <https://www.gnu.org/licenses/>.
*/
#include <cstring>
#include <stdio.h>
#include "config.hpp"
#include "streams.hpp"
int in_callback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
auto ctrl = (Controller*)userData;
if (ctrl->sync_stage == -1) {
ctrl->echoes->sync_pos_blk_write();
ctrl->sync_stage = 0;
}
if (ctrl->sync_stage == 0) {
ctrl->echoes->write((int16_t*)input); // updates slice of echoes spectrogram, inter alia
}
if (statusFlags & paInputOverflow) {
fprintf(stderr, "InputOverflow\n");
}
if (statusFlags & paInputUnderflow) {
fprintf(stderr, "InputUnderflow\n");
}
return paContinue;
}
int out_callback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
auto ctrl = (Controller *)userData;
ctrl->ensemble->react_and_read(ctrl->echoes->spectrogram, ctrl->echoes->pos_blk_read, (int16_t*)output); // updates slice of synth spectrogram, inter alia
if (!ctrl->do_synth_out) {
memset(output, 0, cfg::BLOCKMEMSIZE);
}
ctrl->echoes->read_add((int16_t*)output, !ctrl->do_echoes_out);
if (ctrl->sync_stage == -2) {
ctrl->sync_stage = -1;
}
if (statusFlags & paOutputOverflow) {
fprintf(stderr, "OutputOverflow\n");
}
if (statusFlags & paOutputUnderflow) {
fprintf(stderr, "OutputUnderflow\n");
}
if (statusFlags & paPrimingOutput) {
fprintf(stderr, "PrimingOutput\n");
}
return paContinue;
}
void Streams::start(Controller* ctrl) {
// Suppress ALSA lib warnings (see https://github.com/PortAudio/portaudio/issues/463)
// From https://stackoverflow.com/questions/24778998/how-to-disable-or-re-route-alsa-lib-logging
// and then https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result
(void)!freopen("/dev/null", "w", stderr);
Pa_Initialize();
(void)!freopen("/dev/tty", "w", stderr);
// FIXME: non-ALSA errors may pass undetected this way... and what about cross-platformness?
// Maybe Pa_OpenDefaultStream() doesn't care, maybe it does...
this->in_stream = NULL;
this->out_stream = NULL;
Pa_OpenDefaultStream(
&(this->in_stream),
cfg::CHANNELS,
0, // input only
paInt16,
cfg::SAMPLERATE,
cfg::BLOCKSIZE,
in_callback,
ctrl
);
Pa_OpenDefaultStream(
&(this->out_stream),
0, // output only
cfg::CHANNELS,
paInt16,
cfg::SAMPLERATE,
cfg::BLOCKSIZE,
out_callback,
ctrl
);
Pa_StartStream(in_stream);
Pa_StartStream(out_stream);
}
void Streams::stop() {
Pa_StopStream(this->in_stream);
Pa_StopStream(this->out_stream);
Pa_CloseStream(this->in_stream);
Pa_CloseStream(this->out_stream);
Pa_Terminate();
}