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
|
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include "sndfile.h"
#include "fmt.h"
/*
* gcc -O2 -o playit-sdl2 playit-sdl2.c -I.. -I../src/include -DHAVE_CONFIG_H -lm `pkg-config sdl2 --cflags --libs` -s ../src/libplayit.a
*/
static song_t * song_load_it(const char *file)
{
slurp_t *s;
song_t *song;
s = slurp(file, NULL, 0);
if (!s) {
printf("failed to open \"%s\"\n", file);
goto _fail;
}
song = csf_allocate();
if (!song) {
printf("failed to allocate song\n");
goto _fail_slurp;
}
if (fmt_it_load_song(song, s, 0) != LOAD_SUCCESS)
goto _fail_song;
unslurp(s);
return song;
_fail_song:
csf_free(song);
_fail_slurp:
unslurp(s);
_fail:
return NULL;
}
static SDL_AudioDeviceID sdl2_open(const char *device)
{
SDL_AudioDeviceID dev;
SDL_AudioSpec aspec = {
.freq = 44100,
.format = AUDIO_S16,
.channels = 2,
.samples = 4096,
};
if (SDL_Init(SDL_INIT_AUDIO) != 0) {
printf("Failed to initialize SDL w/audio!\n");
return -1;
}
dev = SDL_OpenAudioDevice(device, 0, &aspec, NULL, 0);
if (dev < 0) {
printf("Failed to open SDL audio device!\n");
return -1;
}
SDL_PauseAudioDevice(dev, 0);
return dev;
}
static void sdl2_close(SDL_AudioDeviceID dev)
{
SDL_CloseAudioDevice(dev);
}
int main(int argc, char *argv[])
{
song_t *song;
uint8_t buf[8192];
int len;
SDL_AudioDeviceID dev;
if (argc != 2) {
printf("usage: %s song.it\n", argv[0]);
goto _fail;
}
song = song_load_it(argv[1]);
if (!song) {
printf("failed to load song!\n");
goto _fail;
}
if (!(dev = sdl2_open(NULL))) {
printf("Failed to open audio!\n");
goto _fail_song;
}
csf_set_current_order(song, 0);
song->repeat_count = 0;
song->buffer_count = 0;
song->stop_at_order = -1;
song->stop_at_row = -1;
song->flags &= ~(SONG_PAUSED | SONG_PATTERNLOOP | SONG_ENDREACHED);
csf_reset_playmarks(song);
csf_set_resampling_mode(song, SRCMODE_LINEAR);
csf_set_wave_config(song, 44100, 16, 2);
while ((len = csf_read(song, buf, sizeof(buf)))) {
int err;
while (SDL_GetQueuedAudioSize(dev) > 8192)
SDL_Delay(10);
if ((err = SDL_QueueAudio(dev, buf, len * 4)) < 0) {
fprintf(stderr, "write failed (%s)\n", SDL_GetError());
break;
}
}
sdl2_close(dev);
return EXIT_SUCCESS;
_fail_song:
/* TODO cleanup song */
_fail:
return EXIT_FAILURE;
}
|