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
|
#define SDL_MAIN_HANDLED
#include <portaudio.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include "include.h"
#include "common/common.h"
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
volatile sig_atomic_t keep_going = 1;
void sigint_handler(int sig_num) {
signal(SIGINT, SIG_IGN);
keep_going = 0;
}
struct blob load_file(char const *const name);
struct userdata userdata = {
.callback = NULL,
.user = NULL,
};
//void audio_callback(void *userdata_void, unsigned char *stream_void, int const length) {
int audio_callback(void const *inBuf, void *outBuf, unsigned long const frameCount, PaStreamCallbackTimeInfo const* timeInfo, PaStreamCallbackFlags statusFlags, void *userdata_void) {
(void) inBuf;
(void) timeInfo;
(void) statusFlags;
struct userdata *user = userdata_void;
user->callback(user->user, outBuf, frameCount * sizeof (float) * 2);
return 0;
}
int (*file_ext(char *file))(struct blob *, struct userdata *);
int main(int argc, char **argv) {
if (argc != 2) {
eprintf("usage: %s audio-file.{mid,mod,xm,it,s3m}\n", argv[0]);
return EXIT_FAILURE;
} else {
int (*module_func)(struct blob *, struct userdata *) = file_ext(argv[1]);
if (module_func == NULL) {
eprintf("%s: unrecognized file extension\n", argv[1]);
return EXIT_FAILURE;
}
struct blob file = load_file(argv[1]);
if (file.data == NULL) {
perror(argv[1]);
return EXIT_FAILURE;
}
if (module_func(&file, &userdata)) {
eprintf("%s: failed to load\n", argv[1]);
return EXIT_FAILURE;
}
}
signal(SIGINT, sigint_handler); // signal(3) claims this method is deprecated, but..
PaError paErr;
if ((paErr = Pa_Initialize()) != paNoError) {
printf("error: Pa_Initialize: %s\n", Pa_GetErrorText(paErr));
goto error;
}
PaStream *stream;
if ((paErr = Pa_OpenDefaultStream(
&stream,
IN_CHANNELS,
OUT_CHANNELS,
paFloat32,
SAMPLE_RATE,
paFramesPerBufferUnspecified,
audio_callback,
&userdata
)) != paNoError) {
printf("error: Pa_OpenDefaultStream: %s\n", Pa_GetErrorText(paErr));
goto error;
}
if ((paErr = Pa_StartStream(stream)) != paNoError) {
printf("error: Pa_StartStream: %s\n", Pa_GetErrorText(paErr));
goto error;
}
while (keep_going) {
Pa_Sleep(1000);
}
if ((paErr = Pa_StopStream(stream)) != paNoError) {
printf("error: Pa_StopStream: %s\n", Pa_GetErrorText(paErr));
goto error;
}
if ((paErr = Pa_CloseStream(stream)) != paNoError) {
printf("error: Pa_CloseStream: %s\n", Pa_GetErrorText(paErr));
goto error;
}
if ((paErr = Pa_Terminate()) != paNoError) {
printf("error: Pa_Terminate: %s\n", Pa_GetErrorText(paErr));
goto error;
}
return EXIT_SUCCESS;
error:
return EXIT_FAILURE;
}
|