94 lines
2.3 KiB
C++
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;
|
|
}
|
|
|