41 {
42 const char* opt_channels = "1";
43 const char* opt_input_txt = NULL;
44 const char* opt_output_au = NULL;
45 char* endptr = NULL;
46 int opt_bits = 16;
47 int opt_rate = 48000;
48 int opt_idx = 0;
49 double opt_freq = 800.0;
50 double opt_dit_period = 80.0;
51 double opt_slope_period = -1.0;
52 uint8_t total_audio_channels;
53 uint8_t select_audio_channels;
55
56 static struct option long_options[] = {
57 {.name = "bits",
58 .has_arg = required_argument,
59 .flag = NULL,
60 .val = 'B'},
61 {.name = "chan",
62 .has_arg = required_argument,
63 .flag = NULL,
64 .val = 'C'},
65 {.name = "rate",
66 .has_arg = required_argument,
67 .flag = NULL,
68 .val = 'R'},
69 {.name = "slope",
70 .has_arg = required_argument,
71 .flag = NULL,
72 .val = 'S'},
73 {.name = "dit-period",
74 .has_arg = required_argument,
75 .flag = NULL,
76 .val = 'd'},
77 {.name = "freq",
78 .has_arg = required_argument,
79 .flag = NULL,
80 .val = 'f'},
81 {.name = NULL, .has_arg = 0, .flag = NULL, .val = 0},
82 };
83
84 while (1) {
85 int c = getopt_long(argc, argv, "B:C:R:S:d:f:", long_options,
86 &opt_idx);
87 if (c == -1) {
88 break;
89 } else if (!c && !long_options[opt_idx].flag) {
90 c = long_options[opt_idx].val;
91 }
92
93 switch (c) {
94 case 0:
95 break;
96 case 'B':
97 opt_bits = strtol(optarg, &endptr, 10);
98 switch (opt_bits) {
99 case 8:
100
102 break;
103 case 16:
104
106 break;
107 case 32:
108 switch (endptr[0]) {
109 case 0:
110 case 'S':
111 case 's':
112
113 audio_encoding
115 break;
116 case 'f':
117 case 'F':
118
119 audio_encoding
121 break;
122 }
123 break;
124 case 64:
125
127 break;
128 default:
129 fprintf(stderr,
130 "Invalid number of bits: %s\n"
131 "Supported values: 8, 16, 32/32s/32f "
132 "and 64\n",
133 optarg);
134 return (1);
135 }
136 break;
137 case 'C':
138 opt_channels = optarg;
139 break;
140 case 'R':
141 opt_rate = atoi(optarg);
142 break;
143 case 'S':
144 opt_slope_period = strtod(optarg, &endptr);
145 if (endptr[0]) {
146 fprintf(stderr, "Invalid slope period: %s\n",
147 optarg);
148 return (1);
149 }
150 break;
151 case 'd':
152 opt_dit_period = strtod(optarg, &endptr);
153 if (endptr[0]) {
154 fprintf(stderr, "Invalid dit period: %s\n",
155 optarg);
156 return (1);
157 }
158 break;
159 case 'f':
160 opt_freq = strtod(optarg, &endptr);
161 if (endptr[0]) {
162 fprintf(stderr, "Invalid frequency: %s\n",
163 optarg);
164 return (1);
165 }
166 break;
167 default:
169 return 1;
170 }
171 }
172
173 if ((argc - optind) != 2) {
175 return 1;
176 }
177 opt_input_txt = argv[optind];
178 opt_output_au = argv[optind + 1];
179
180 switch (opt_channels[0]) {
181 case '1':
182 case 'm':
183 case 'M':
184
185 total_audio_channels = 1;
186 select_audio_channels = 1;
187 break;
188 case '2':
189 case 's':
190 case 'S':
191
192 total_audio_channels = 2;
193 select_audio_channels = UINT8_MAX;
194 break;
195 case 'l':
196 case 'L':
197
198 total_audio_channels = 2;
199 select_audio_channels = 1;
200 break;
201 case 'r':
202 case 'R':
203
204 total_audio_channels = 2;
205 select_audio_channels = 2;
206 break;
207 default:
208 printf("Unknown channel mode: %s\n", opt_channels);
209 return (1);
210 }
211
212 if (opt_slope_period < 0) {
213 opt_slope_period = 0.2 * opt_dit_period;
214 }
215
218
220 opt_slope_period, opt_rate,
222 {
224 audio_encoding,
225 total_audio_channels);
226 if (res < 0) {
227 fprintf(stderr, "Failed to open output file %s: %s\n",
228 opt_output_au, strerror(-res));
229 }
230 }
231
233
234 double samples[total_audio_channels];
235
236
238
239
240 for (uint8_t ch = 0; ch < total_audio_channels; ch++) {
241 if (select_audio_channels & (1 << ch)) {
242 samples[ch] = cw.output;
243 } else {
244 samples[ch] = 0.0;
245 }
246 }
247
248
250 &au, total_audio_channels, samples);
251 if (au_res < 0) {
252 fprintf(stderr, "Failed to write audio samples: %s\n",
253 strerror(-au_res));
254 return (2);
255 }
256 }
257
258 {
260 if (au_res < 0) {
261 fprintf(stderr,
262 "Failed to close audio output file: %s\n",
263 strerror(-au_res));
264 return (2);
265 }
266 }
267
268 return 0;
269}
#define SSTVENC_CW_MOD_STATE_DONE
void sstvenc_cw_compute(struct sstvenc_cw_mod *const cw)
void sstvenc_cw_init(struct sstvenc_cw_mod *const cw, const char *text, double amplitude, double frequency, double dit_period, double slope_period, uint32_t sample_rate, uint8_t time_unit)
int sstvenc_sunau_enc_write(struct sstvenc_sunau *const enc, size_t n_samples, const double *samples)
int sstvenc_sunau_enc_init(struct sstvenc_sunau *const enc, const char *path, uint32_t sample_rate, uint8_t encoding, uint8_t channels)
int sstvenc_sunau_enc_close(struct sstvenc_sunau *const enc)
#define SSTVENC_TS_UNIT_MILLISECONDS
static void show_usage(const char *prog_name)