mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-07-30 16:29:15 +02:00
add alsa output to STCode
This commit is contained in:
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"port": 13452,
|
"port": 13452,
|
||||||
"time": 1737621156918,
|
"time": 1737734479782,
|
||||||
"version": "0.0.3"
|
"version": "0.0.3"
|
||||||
}
|
}
|
||||||
Vendored
+5
-1
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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