Banner/main.cpp
2023-12-10 15:12:47 +01:00

94 lines
2.3 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sndfile.h>
#include <math.h>
#include <vector>
#include "banner.h"
#include "fft.h"
using namespace std;
static constexpr int ORDER = 8;
static constexpr int TAPS = (1 << ORDER);
static constexpr int HALF = TAPS >> 1;
static constexpr int OFS = 20;
static CFFT fft (ORDER);
static vector<double> mono;
static bool odd = false;
void cputs (const char * s) {
odd = ! odd;
const complex plus (0.0, 256.0), minus (0.0, -256.0);
complex data [TAPS];
memset (&data,0, TAPS * sizeof(complex));
int n = 0;
while (true) {
const char c = s [n];
if (c == '\0') break;
if (c == '#' ) {
const bool sign = (n & 1) xor odd;
// Střídání fáze 0/180 dost potlačí rozmazání spektra.
const complex fill = sign ? plus : minus;
const int k = n + OFS;
data[k] = fill;
data[TAPS - k] = fill;
}
putchar(c);
n += 1;
}
//printf("\tlen=%d\n", n);
fft.Inverse(data, false);
for (int i=0; i<TAPS; i++) {
mono.push_back (data[i].im());
}
}
static bool WriteSound (const char * filename = "output.vaw") {
printf("len=%zd\n", mono.size());
double min = 1.0e100, max = -1.0e100;
for (double e: mono) {
if (e < min) min = e;
if (e > max) max = e;
}
printf("min=%g, max=%g\n", min, max);
double z = abs(min) > abs(max) ? abs(min) : abs(max);
z = 32000.0 / z;
vector<short> data (mono.size());
int n = 0;
for (double e: mono) {
data[n] = ::lround (e * z);
n += 1;
}
SF_INFO info;
memset (&info, 0, sizeof(SF_INFO));
info.channels = 1;
info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
info.samplerate = 8000;
if (sf_format_check (&info) == SF_FALSE) {
fprintf(stderr, "bad output format\n");
return false;
}
SNDFILE * outfile = sf_open (filename, SFM_WRITE, &info);
if (!outfile) {
fprintf(stderr, "cannot open output file \"%s\"\n", filename);
return false;
}
sf_write_short (outfile, data.data(), data.size());
sf_close (outfile);
return true;
}
int main (int argc, char *argv[]) {
if (argc < 2) {
printf("Usage:\n\t%s \"Text to spectrogram\"\n", argv[0]);
return 0;
}
const char * buffer = argv[1];
for (const char * p = buffer; *p; p++) {
banchr (*p);
}
WriteSound ("test.vaw");
return 0;
}