mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-02-26 19:23:51 +01:00
add alsa output to STCode
This commit is contained in:
2
.vscode/.server-controller-port.log
vendored
2
.vscode/.server-controller-port.log
vendored
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"port": 13452,
|
||||
"time": 1737621156918,
|
||||
"time": 1737734479782,
|
||||
"version": "0.0.3"
|
||||
}
|
||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -12,6 +12,10 @@
|
||||
"options.h": "c",
|
||||
"random": "c",
|
||||
"__locale": "c",
|
||||
"complex": "c"
|
||||
"complex": "c",
|
||||
"stdbool.h": "c",
|
||||
"format": "c",
|
||||
"ios": "c",
|
||||
"stdint.h": "c"
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ As far as i've tested it (29-31 december) it's been fine but after a fix it was
|
||||
Also i'd recommend to use the SSB version because it's more spectrum effiecent
|
||||
but SSB has slightly more cpu usage
|
||||
|
||||
This supports alsa output
|
||||
|
||||
# PSTCode
|
||||
This is a yet another version of a Stereo encoder, however for the OIRT band which is in use in Russia, Belarus and other countries
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/error.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
@@ -10,7 +8,9 @@
|
||||
#include "options.h"
|
||||
|
||||
//#define SSB
|
||||
#ifdef SSB
|
||||
//#define USB
|
||||
#endif
|
||||
|
||||
#include "../lib/constants.h"
|
||||
#include "../lib/oscillator.h"
|
||||
@@ -23,9 +23,16 @@
|
||||
|
||||
#define INPUT_DEVICE "real_real_tx_audio_input.monitor"
|
||||
#define OUTPUT_DEVICE "alsa_output.platform-soc_sound.stereo-fallback"
|
||||
#define ALSA_OUTPUT // Output, not input or both
|
||||
#define BUFFER_SIZE 512
|
||||
#define CLIPPER_THRESHOLD 0.525 // Adjust this as needed
|
||||
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/error.h>
|
||||
#ifdef ALSA_OUTPUT
|
||||
#include <alsa/asoundlib.h>
|
||||
#endif
|
||||
|
||||
#define MONO_VOLUME 0.45f // L+R Signal
|
||||
#define PILOT_VOLUME 0.09f // 19 KHz Pilot
|
||||
#define STEREO_VOLUME 0.45f // L-R signal possibly can be set to .9 because im not sure if usb will be 2 times stronger than dsb-sc
|
||||
@@ -88,6 +95,8 @@ int main() {
|
||||
.prebuf = buffer_prebuf
|
||||
};
|
||||
|
||||
int open_pulse_error;
|
||||
|
||||
printf("Connecting to input device... (%s)\n", INPUT_DEVICE);
|
||||
|
||||
pa_simple *input_device = pa_simple_new(
|
||||
@@ -99,15 +108,16 @@ int main() {
|
||||
&stereo_format,
|
||||
NULL,
|
||||
&input_buffer_atr,
|
||||
NULL
|
||||
&open_pulse_error
|
||||
);
|
||||
if (!input_device) {
|
||||
fprintf(stderr, "Error: cannot open input device.\n");
|
||||
fprintf(stderr, "Error: cannot open input device: %s\n", pa_strerror(open_pulse_error));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Connecting to output device... (%s)\n", OUTPUT_DEVICE);
|
||||
|
||||
#ifndef ALSA_OUTPUT
|
||||
pa_simple *output_device = pa_simple_new(
|
||||
NULL,
|
||||
"StereoEncoder",
|
||||
@@ -117,13 +127,40 @@ int main() {
|
||||
&mono_format,
|
||||
NULL,
|
||||
&output_buffer_atr,
|
||||
NULL
|
||||
&open_pulse_error
|
||||
);
|
||||
if (!output_device) {
|
||||
fprintf(stderr, "Error: cannot open output device.\n");
|
||||
fprintf(stderr, "Error: cannot open output device: %s\n", pa_strerror(open_pulse_error));
|
||||
pa_simple_free(input_device);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
snd_pcm_hw_params_t *output_params;
|
||||
snd_pcm_t *output_handle;
|
||||
int output_error = snd_pcm_open(&output_handle, OUTPUT_DEVICE, SND_PCM_STREAM_PLAYBACK, 0);
|
||||
if(output_error < 0) {
|
||||
fprintf(stderr, "Error: cannot open output device: %s\n", snd_strerror(output_error));
|
||||
pa_simple_free(input_device);
|
||||
return 1;
|
||||
}
|
||||
snd_pcm_hw_params_malloc(&output_params);
|
||||
snd_pcm_hw_params_any(output_handle, output_params);
|
||||
snd_pcm_hw_params_set_access(output_handle, output_params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
snd_pcm_hw_params_set_format(output_handle, output_params, SND_PCM_FORMAT_FLOAT); // Same as pulse's Float32NE
|
||||
snd_pcm_hw_params_set_channels(output_handle, output_params, 1);
|
||||
unsigned int rate = SAMPLE_RATE;
|
||||
int dir;
|
||||
snd_pcm_hw_params_set_rate_near(output_handle, output_params, &rate, &dir);
|
||||
snd_pcm_uframes_t frames = BUFFER_SIZE;
|
||||
snd_pcm_hw_params_set_period_size_near(output_handle, output_params, &frames, &dir); // i don't have a clue why like this
|
||||
output_error = snd_pcm_hw_params(output_handle, output_params);
|
||||
if(output_error < 0) {
|
||||
fprintf(stderr, "Error: cannot open output device: %s\n", snd_strerror(output_error));
|
||||
snd_pcm_close(output_handle);
|
||||
pa_simple_free(input_device);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Oscillator pilot_osc;
|
||||
init_oscillator(&pilot_osc, 19000.0, SAMPLE_RATE); // Pilot, it's there to indicate stereo and as a refrence signal with the stereo carrier
|
||||
@@ -216,15 +253,24 @@ int main() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef ALSA_OUTPUT
|
||||
if (pa_simple_write(output_device, mpx, sizeof(mpx), &pulse_error) < 0) {
|
||||
fprintf(stderr, "Error writing to output device: %s\n", pa_strerror(pulse_error));
|
||||
to_run = 0;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
snd_pcm_writei(output_handle, mpx, sizeof(mpx));
|
||||
#endif
|
||||
}
|
||||
printf("Cleaning up...\n");
|
||||
pa_simple_free(input_device);
|
||||
#ifndef ALSA_OUTPUT
|
||||
pa_simple_free(output_device);
|
||||
#else
|
||||
snd_pcm_drain(output_handle);
|
||||
snd_pcm_free(output_handle);
|
||||
#endif
|
||||
#ifdef SSB
|
||||
exit_hilbert(&hilbert);
|
||||
exit_delay_line(&monoDelay);
|
||||
|
||||
48
wip/tv_encoder.c
Normal file
48
wip/tv_encoder.c
Normal file
@@ -0,0 +1,48 @@
|
||||
// This will encode a black and white TV signal using a luminance value, how does it work?
|
||||
/*
|
||||
It encodes the luminance into negative values, so totally white pixel should output -1, a black one should be 0
|
||||
|
||||
Every new line it sends a 0.5, every frame it is a 1.0
|
||||
*/
|
||||
|
||||
#include "../lib/fm_modulator.h"
|
||||
|
||||
unsigned int rgb_to_luminance(unsigned int r, unsigned int g, unsigned int b) {
|
||||
return (unsigned int)(0.299 * r + 0.587 * g + 0.114 * b);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
int pixel;
|
||||
int lines;
|
||||
int pixels;
|
||||
} TVEncoder;
|
||||
|
||||
void init_tv_modulator(TVEncoder* tv, int lines, int pixels) {
|
||||
tv->pixels = pixels;
|
||||
tv->lines = lines;
|
||||
tv->line = 0;
|
||||
tv->pixel = 0;
|
||||
}
|
||||
|
||||
float tv_encode(TVEncoder* tv, float luminance) {
|
||||
float normalized_luminance = luminance / 255.0f; // Normalize luminance to [0, 1]
|
||||
|
||||
if (tv->line < tv->lines) {
|
||||
if (tv->pixel < tv->pixels) {
|
||||
// Process pixel within the current line
|
||||
tv->pixel++;
|
||||
return -normalized_luminance;
|
||||
} else {
|
||||
// End of line: reset pixel counter and move to the next line
|
||||
tv->pixel = 0;
|
||||
tv->line++;
|
||||
return 0.5f;
|
||||
}
|
||||
} else {
|
||||
// End of frame: reset frame counters
|
||||
tv->line = 0;
|
||||
tv->pixel = 0;
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user