fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/utils/aym/main.c *
7 * Created: 2015-05-21 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2015-2022 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
28
29#include <lib/getopt.h>
30
31#include <drivers/sound/sound.h>
32
33
34const char *arg0 = NULL;
35
36char par_verbose = 0;
37
38unsigned long par_srate = 48000;
39
40static unsigned long par_lowpass = 0;
41static char par_highpass = 0;
42
43static const char *par_driver = "oss:lowpass=0";
44static char par_driver_tmp[256];
45
46static unsigned long par_threshold = 0;
47
48static unsigned long par_mark = 0;
49
50
51static pce_option_t opts[] = {
52 { '?', 0, "help", NULL, "Print usage information" },
53 { 'd', 0, "decode", NULL, "Decode AYM to text" },
54 { 'e', 0, "encode", NULL, "Encode text to AYM" },
55 { 'h', 0, "highpass", NULL, "Enable the highpass filter [no]" },
56 { 'i', 1, "input", "filename", "Set the input file name" },
57 { 'l', 1, "lowpass", "freq", "Set lowpass frequency [0]" },
58 { 'm', 1, "mark", "pos", "Mark a file position when decoding" },
59 { 'o', 1, "output", "filename", "Set the output file name" },
60 { 'p', 0, "play", NULL, "Play an AYM file" },
61 { 'r', 1, "srate", "rate", "Set the sample rate [48000]" },
62 { 's', 1, "driver", "driver", "Set the sound driver [oss]" },
63 { 't', 1, "threshold", "delay", "Set the delay threshold [0]" },
64 { 'V', 0, "version", NULL, "Print version information" },
65 { 'w', 1, "wav", "file", "Save to a WAV file" },
66 { -1, 0, NULL, NULL, NULL }
67};
68
69
70static
71void print_help (void)
72{
73 pce_getopt_help (
74 "aym: encode and decode PCE AYM files",
75 "usage: aym [options] [input [output]]",
76 opts
77 );
78
79 fflush (stdout);
80}
81
82static
83void print_version (void)
84{
85 fputs (
86 "aym version " PCE_VERSION_STR
87 "\n\n"
88 "Copyright (C) 2015-" PCE_YEAR " Hampa Hug <hampa@hampa.ch>\n",
89 stdout
90 );
91
92 fflush (stdout);
93}
94
95unsigned long aym_get_uint32_be (const void *buf, unsigned i)
96{
97 unsigned long val;
98 const unsigned char *tmp;
99
100 tmp = (const unsigned char *) buf + i;
101
102 val = tmp[0] & 0xff;
103 val = (val << 8) | (tmp[1] & 0xff);
104 val = (val << 8) | (tmp[2] & 0xff);
105 val = (val << 8) | (tmp[3] & 0xff);
106
107 return (val);
108}
109
110void aym_set_uint32_be (void *buf, unsigned i, unsigned long val)
111{
112 unsigned char *tmp;
113
114 tmp = (unsigned char *) buf + i;
115
116 tmp[0] = (val >> 24) & 0xff;
117 tmp[1] = (val >> 16) & 0xff;
118 tmp[2] = (val >> 8) & 0xff;
119 tmp[3] = val;
120}
121
122int main (int argc, char **argv)
123{
124 int r, op;
125 char **optarg;
126 const char *inp, *out;
127
128 if (argc < 2) {
129 print_help();
130 return (1);
131 }
132
133 arg0 = argv[0];
134
135 op = 0;
136
137 inp = NULL;
138 out = NULL;
139
140 while (1) {
141 r = pce_getopt (argc, argv, &optarg, opts);
142
143 if (r == GETOPT_DONE) {
144 break;
145 }
146
147 if (r < 0) {
148 return (1);
149 }
150
151 switch (r) {
152 case '?':
153 print_help();
154 return (0);
155
156 case 'V':
157 print_version();
158 return (0);
159
160 case 'd':
161 op = 0;
162 break;
163
164 case 'e':
165 op = 1;
166 break;
167
168 case 'h':
169 par_highpass = 1;
170 break;
171
172 case 'i':
173 inp = optarg[0];
174 break;
175
176 case 'l':
177 par_lowpass = strtoul (optarg[0], NULL, 0);
178 break;
179
180 case 'm':
181 par_mark = strtoul (optarg[0], NULL, 0);
182 break;
183
184 case 'o':
185 out = optarg[0];
186 break;
187
188 case 'p':
189 op = 2;
190 break;
191
192 case 'r':
193 par_srate = strtoul (optarg[0], NULL, 0);
194 break;
195
196 case 's':
197 par_driver = optarg[0];
198 break;
199
200 case 't':
201 par_threshold = strtoul (optarg[0], NULL, 0);
202 break;
203
204 case 'w':
205 op = 2;
206 sprintf (par_driver_tmp, "wav:wav=%s:wavfilter=0", optarg[0]);
207 par_driver = par_driver_tmp;
208 break;
209
210 case 0:
211 if (inp == NULL) {
212 inp = optarg[0];
213 }
214 else if (out == NULL) {
215 out = optarg[0];
216 }
217 else {
218 fprintf (stderr, "%s: too many files (%s)\n", arg0, optarg[0]);
219 return (1);
220 }
221 break;
222
223 default:
224 return (1);
225 }
226 }
227
228 if (op == 0) {
229 r = aym_decode (inp, out, par_threshold, par_mark);
230 }
231 else if (op == 1) {
232 r = aym_encode (inp, out, par_threshold);
233 }
234 else {
235 r = aym_play (inp, par_driver, par_lowpass, par_highpass);
236 }
237
238 if (r) {
239 return (1);
240 }
241
242 return (0);
243}