annotate pmd_play.c @ 10:e3849cd10ad3 default tip

Build an intermediary fmgen.a archive.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Mon, 08 Sep 2014 17:44:53 +0200
parents c4218fbe158f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
1 #include <stdio.h>
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2 #include <stdint.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 #include <string.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
4 #include <fcntl.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
5 #include <unistd.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 #include <sys/stat.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 #include <math.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8 #include <getopt.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 #include <windows.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 #include <mmsystem.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 int wave_out_open(HWAVEOUT *hWaveOut, uint32_t rate, uint8_t channels);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 void wave_out_close(HWAVEOUT hWaveOut);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14 void writeAudio(HWAVEOUT hWaveOut, void *data, uint32_t size);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
15 #else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
16 int oss_audio_open(uint32_t oss_audio_rate, uint8_t nchannels);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17 int alsa_audio_open(uint32_t *rate, uint8_t channels, uint32_t *_ver, int mode);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
18 int alsa_audio_close(int snd_fd);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19 long snd_pcm_writei(int snd_fd, const void *buffer, unsigned long size);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20 int snd_pcm_prepare(int snd_fd);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 #ifdef USE_ALSA
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22 #include <errno.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25 #include "pmdwin.h"
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 #ifndef O_BINARY
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 #define O_BINARY 0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 static uint32_t atoui(const uint8_t *str) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
32 uint32_t c, num = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 while(1) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 c = *str++ - 0x30;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 if(c > 9) break;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 num = (num << 1) + (num << 3) + c;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38 return num;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
39 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
40
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41 static const unsigned char static_hdr_portion[20] = {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42 0x52, 0x49, 0x46, 0x46, 0xFF, 0xFF, 0xFF, 0x7F,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44 0x10, 0x00, 0x00, 0x00
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
45 };
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
46
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 typedef struct _WAVHeader {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 uint16_t wav_id;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49 uint16_t channels;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 uint32_t samplerate;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51 uint32_t bitrate;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52 uint32_t block_align;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
53 uint32_t pad0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
54 uint32_t pad1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
55 } __attribute__((packed)) WAVHeader;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
56
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
57 static void write_wav_header(int fd, uint32_t rate)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
58 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
59 WAVHeader w;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
60 write(fd, &static_hdr_portion, 20);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
61
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
62 w.wav_id = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
63 w.channels = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
64 w.samplerate = rate;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
65 w.bitrate = rate*2;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
66 w.block_align = 0x00100010;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
67 w.pad0 = 0x61746164;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
68 w.pad1 = 0x7fffffff;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
69 write(fd, &w, sizeof(WAVHeader));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
70 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
71
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
72 //=============================================================================
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
73 // Load PMD data from file into memory. Uses mmap() on both Windows and *nix.
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
74 // Originally in pmdwin.cpp, moved here to minimize platform-specific code
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
75 // in pmdwin.cpp
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
76 //=============================================================================
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
77 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78 static int music_load(char *filename)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
79 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
80 HANDLE mapped_file, h;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
81 int result;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
82 size_t size;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
83 uchar *musbuf;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
84 struct stat st;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
85
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
86 mapped_file = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
87 h = CreateFileMapping(mapped_file, NULL, PAGE_READWRITE, 0, 0, NULL);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
88 if(!h) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
89 return ERR_OPEN_MUSIC_FILE;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
90 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
91 stat(filename, &st);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
92 musbuf = (uchar*)MapViewOfFile(h, FILE_MAP_READ, 0, 0, 0);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
93 CloseHandle(h);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
94 CloseHandle(mapped_file);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
95 size = st.st_size;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
96 result = music_load3(musbuf, size);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
97 return result;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
98 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
99 #else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
100 static int music_load(char *filename)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
101 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
102 int fd = -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
103 int result;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
104 size_t size;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
105 uchar musbuf[mdata_def*1024];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
106
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
107 if((fd = open(filename, O_RDONLY)) < 0) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
108 return ERR_OPEN_MUSIC_FILE;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
109 }
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
110
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
111 size = read(fd, musbuf, sizeof(musbuf));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
112 close(fd);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
113 result = music_load3(musbuf, size);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
114 return result;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
115 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
116 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
117
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
118 static void usage(char *argv0) {
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
119 const char *usage_str =
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
120 "%s [-f <output file>] [-l <loop count>] [-m <device mask>] [-c <channel mask>] [-t <time>] [-r <samplerate>] <PMD File>\n\
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
121 -f - Write output to wavfile\n\
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
122 -l - Loop n times (default is once - use 0 for infinite loop)\n\
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
123 -m - Device mask: 1 - OPNA, 2 - PSG, 4 - Rhythm (or them together)\n\
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
124 -c - Channel mask: 1,2,4,8,16,32 are OPNA channels 1-6, 64,128,256 are PSG channels 1-3. Once again, or them together\n\
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
125 -t - Play song for n seconds\n\
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
126 -r - Set the output sample rate\n\n";
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
127 fprintf(stderr, usage_str, argv0);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
128 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
129
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
130 int main(int argc, char **argv) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
131 uint32_t i, frameno, samplerate_out = SOUND_44K, infloop = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
132 uint32_t pmd_length = 0, pmd_loopcount = 2;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
133 int opt, j, out_fd = -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
134 uint8_t tofile = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
135 int16_t pcmbuf[8192];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
136 char pmd_title[1024];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
137 char pmd_compo[1024];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
138 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
139 HWAVEOUT hWaveOut;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
140 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
141 char buf[1024];
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
142 pmdwininit();
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
143
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
144 while((opt = getopt(argc, argv, "f:l:m:c:t:r:")) != -1) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
145 switch(opt) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
146 case 'f':
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
147 tofile = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
148 out_fd = open(optarg, O_WRONLY|O_CREAT|O_APPEND|O_BINARY, 0644);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
149 break;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
150 case 'l':
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
151 pmd_loopcount = atoui((uint8_t*)optarg);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
152 if(!pmd_loopcount) infloop = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
153 break;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
154 case 'c':
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
155 setchanmask(atoui((uint8_t*)optarg));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
156 break;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
157 case 'm':
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
158 setdevmask(atoui((uint8_t*)optarg));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
159 break;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
160 case 't':
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
161 pmd_length = atoui((uint8_t*)optarg)*1000;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
162 break;
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
163 case 'r':
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
164 samplerate_out = atoui((uint8_t*)optarg);
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
165 break;
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
166 default:
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
167 usage(argv[0]);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
168 return 1;
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
169 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
170 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
171
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
172 if(!tofile) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
173 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
174 if(!wave_out_open(&hWaveOut, samplerate_out, 1)) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
175 #else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
176 #ifdef USE_ALSA
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
177 if((out_fd = alsa_audio_open(&samplerate_out, 1, NULL, 0)) < 0) {
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
178 #else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
179 if((out_fd = oss_audio_open(samplerate_out, 1)) < 0) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
180 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
181 #endif
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
182 fprintf(stderr, "Cannot open sound device, exiting.\n");
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
183 return 3;
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
184 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
185 } else {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
186 write_wav_header(out_fd, samplerate_out);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
187 }
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
188 if (!argv[optind] || optind + 1 != argc) {
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
189 usage(argv[0]);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
190 return 1;
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
191 }
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
192 if (music_load(argv[optind]) == ERR_OPEN_MUSIC_FILE) {
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
193 fprintf(stderr, "Cannot open music file ā€œ%sā€, exiting.\n", argv[optind]);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
194 return 2;
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
195 }
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
196 getmemo3(pmd_title, NULL, 0, 1);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
197 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
198 SetConsoleOutputCP(65001); // UTF-8
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
199 #endif
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
200 printf("Title = %s\n", pmd_title);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
201 getmemo3(pmd_compo, NULL, 0, 2);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
202 printf("Composer = %s\n", pmd_compo);
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
203 setpcmrate(samplerate_out);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
204 music_start();
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
205 i = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
206 if(pmd_length != 0) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
207 frameno = lrintf(((float)pmd_length*(float)samplerate_out)/(4096.0f*1000.0f));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
208 } else {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
209 frameno = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
210 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
211 while(getloopcount() < pmd_loopcount || infloop || i < frameno) {
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
212 getstatus(buf, 1023);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
213 printf("\r%s", buf);
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
214 fflush(stdout);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
215 getpcmdata(pcmbuf, 4096);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
216 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
217 if(!tofile) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
218 writeAudio(hWaveOut, pcmbuf, 8192);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
219 } else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
220 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
221 #ifdef USE_ALSA
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
222 if(!tofile) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
223 j = snd_pcm_writei(out_fd, pcmbuf, 2048);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
224 if(j == -EPIPE) {
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
225 snd_pcm_prepare(out_fd);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
226 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
227 } else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
228 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
229 write(out_fd, pcmbuf, 8192);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
230 i++;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
231 }
4
c8875256b767 Use stdio for console output, update usage, and use sensible exit values.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 0
diff changeset
232 fputc('\n', stdout);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
233 #if defined(WIN32) || defined(WIN64)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
234 if(!tofile) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
235 wave_out_close(hWaveOut);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
236 } else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
237 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
238 #ifdef USE_ALSA
5
c4218fbe158f Fix indent in pmd_play.c.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 4
diff changeset
239 alsa_audio_close(out_fd);
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
240 #else
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
241 close(out_fd);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
242 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
243 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
244 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
245