add alsa output to STCode

This commit is contained in:
2025-01-24 17:24:46 +01:00
parent 7096a6e572
commit f5b6a12486
5 changed files with 108 additions and 8 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"port": 13452, "port": 13452,
"time": 1737621156918, "time": 1737734479782,
"version": "0.0.3" "version": "0.0.3"
} }
+5 -1
View File
@@ -12,6 +12,10 @@
"options.h": "c", "options.h": "c",
"random": "c", "random": "c",
"__locale": "c", "__locale": "c",
"complex": "c" "complex": "c",
"stdbool.h": "c",
"format": "c",
"ios": "c",
"stdint.h": "c"
} }
} }
+2
View File
@@ -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 Also i'd recommend to use the SSB version because it's more spectrum effiecent
but SSB has slightly more cpu usage but SSB has slightly more cpu usage
This supports alsa output
# PSTCode # 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 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
+52 -6
View File
@@ -1,6 +1,4 @@
#include <stdio.h> #include <stdio.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
@@ -10,7 +8,9 @@
#include "options.h" #include "options.h"
//#define SSB //#define SSB
#ifdef SSB
//#define USB //#define USB
#endif
#include "../lib/constants.h" #include "../lib/constants.h"
#include "../lib/oscillator.h" #include "../lib/oscillator.h"
@@ -23,9 +23,16 @@
#define INPUT_DEVICE "real_real_tx_audio_input.monitor" #define INPUT_DEVICE "real_real_tx_audio_input.monitor"
#define OUTPUT_DEVICE "alsa_output.platform-soc_sound.stereo-fallback" #define OUTPUT_DEVICE "alsa_output.platform-soc_sound.stereo-fallback"
#define ALSA_OUTPUT // Output, not input or both
#define BUFFER_SIZE 512 #define BUFFER_SIZE 512
#define CLIPPER_THRESHOLD 0.525 // Adjust this as needed #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 MONO_VOLUME 0.45f // L+R Signal
#define PILOT_VOLUME 0.09f // 19 KHz Pilot #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 #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 .prebuf = buffer_prebuf
}; };
int open_pulse_error;
printf("Connecting to input device... (%s)\n", INPUT_DEVICE); printf("Connecting to input device... (%s)\n", INPUT_DEVICE);
pa_simple *input_device = pa_simple_new( pa_simple *input_device = pa_simple_new(
@@ -99,15 +108,16 @@ int main() {
&stereo_format, &stereo_format,
NULL, NULL,
&input_buffer_atr, &input_buffer_atr,
NULL &open_pulse_error
); );
if (!input_device) { 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; return 1;
} }
printf("Connecting to output device... (%s)\n", OUTPUT_DEVICE); printf("Connecting to output device... (%s)\n", OUTPUT_DEVICE);
#ifndef ALSA_OUTPUT
pa_simple *output_device = pa_simple_new( pa_simple *output_device = pa_simple_new(
NULL, NULL,
"StereoEncoder", "StereoEncoder",
@@ -117,13 +127,40 @@ int main() {
&mono_format, &mono_format,
NULL, NULL,
&output_buffer_atr, &output_buffer_atr,
NULL &open_pulse_error
); );
if (!output_device) { 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); pa_simple_free(input_device);
return 1; 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; 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 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 #endif
} }
#ifndef ALSA_OUTPUT
if (pa_simple_write(output_device, mpx, sizeof(mpx), &pulse_error) < 0) { 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)); fprintf(stderr, "Error writing to output device: %s\n", pa_strerror(pulse_error));
to_run = 0; to_run = 0;
break; break;
} }
#else
snd_pcm_writei(output_handle, mpx, sizeof(mpx));
#endif
} }
printf("Cleaning up...\n"); printf("Cleaning up...\n");
pa_simple_free(input_device); pa_simple_free(input_device);
#ifndef ALSA_OUTPUT
pa_simple_free(output_device); pa_simple_free(output_device);
#else
snd_pcm_drain(output_handle);
snd_pcm_free(output_handle);
#endif
#ifdef SSB #ifdef SSB
exit_hilbert(&hilbert); exit_hilbert(&hilbert);
exit_delay_line(&monoDelay); exit_delay_line(&monoDelay);
+48
View 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;
}
}