Files
e36/martin.c

79 lines
2.1 KiB
C

#include "martin.h"
#include "image.h"
#include "sstv.h"
#include "wav.h"
#include <stdint.h>
const martin_mode_t MARTIN_M1 = {
.vis_code = 0x2C, // hex (dd -> 44d)
.width = 320,
.height = 256,
.sync_ms = 4.862,
.sync_porch_ms = 0.572,
.separator_ms = 0.572,
.scan_ms = 146.432, // per channel , per line
};
const martin_mode_t MARTIN_M2 = {
.vis_code = 0x28, // hex (dd -> 40d)
.width = 320,
.height = 256,
.sync_ms = 4.862,
.sync_porch_ms = 0.572,
.separator_ms = 0.572,
.scan_ms = 73.216, // half of M1
};
static void scan_line_channel(wav_t *wav, uint8_t *line, int width, int channel, double scan_ms) {
double px_ms = scan_ms / width;
for (int x = 0; x < width; x++) {
uint8_t val = line[x * 3 + channel];
double freq = 1500.0 + val * 3.1372549;
sstv_tone(wav, freq, px_ms);
}
}
void martin_encode_image(wav_t *wav, uint8_t *rgb, const martin_mode_t *mode) {
for (int y = 0; y < mode->height; y++) {
uint8_t *line = &rgb[y * mode->width * 3];
sstv_tone(wav, 1200.0, mode->sync_ms); // sync pulse
sstv_tone(wav, 1500.0, mode->sync_porch_ms); // sync porch
scan_line_channel(wav, line, mode->width, 1, mode->scan_ms); // G
sstv_tone(wav, 1500.0, mode->separator_ms);
scan_line_channel(wav, line, mode->width, 2, mode->scan_ms); // B
sstv_tone(wav, 1500.0, mode->separator_ms);
scan_line_channel(wav, line, mode->width, 0, mode->scan_ms); // R
sstv_tone(wav, 1500.0, mode->separator_ms);
}
}
int sstv_encode_martin(const char *input_image, const char *output_wav, const martin_mode_t *mode) {
image_t img, resized;
wav_t wav;
if (!image_load(&img, input_image)) {
return 0;
}
if (!image_resize(&img, &resized, mode->width, mode->height)) {
image_free(&img);
return 0;
}
if (!wave_open(&wav, output_wav, 44100)) {
image_free(&img);
image_free_raw(&resized);
return 0;
}
sstv_vis_header_ex(&wav, mode->vis_code);
martin_encode_image(&wav, resized.data, mode);
wave_close(&wav);
image_free(&img);
image_free_raw(&resized);
return 1;
}