diff --git a/README.md b/README.md index b1bfc6a..7886ef4 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ To test stereophonic audio, you can try the file `stereo_44100.wav` provided. The more general syntax for running Pi-FM-RDS is as follows: ``` -pi_fm_rds [-freq freq] [-audio file] [-ppm ppm_error] [-pi pi_code] [-ps ps_text] [-rt rt_text] +pi_fm_rds [-freq freq] [-audio file] [-ppm ppm_error] [-pi pi_code] [-ps ps_text] [-rt rt_text] [-cutoff cutoff_freq] [-preemph preemphasis_mode] ``` All arguments are optional: @@ -65,6 +65,8 @@ All arguments are optional: * `-rt` specifies the radiotext (RT) to be transmitted. Limit: 64 characters. Example: `-rt 'Hello, world!'`. * `-ctl` specifies a named pipe (FIFO) to use as a control channel to change PS and RT at run-time (see below). * `-ppm` specifies your Raspberry Pi's oscillator error in parts per million (ppm), see below. +* `-cutoff` specifies the cutoff frequency (in Hz, 'compliant' for 15,000Hz or 'quality' for 22,050Hz) used by Pi-FM-RDS' internal lowpass filter. Values greater than 15000 are not compliant. Use carefully. +* `-preemph` specifies which preemph should be used, since it differs from location. For Europe choose 'eu', for the US choose 'us'. By default the PS changes back and forth between `Pi-FmRds` and a sequence number, starting at `00000000`. The PS changes around one time per second. diff --git a/src/fm_mpx.c b/src/fm_mpx.c index fd0b7fa..82a62c0 100644 --- a/src/fm_mpx.c +++ b/src/fm_mpx.c @@ -66,6 +66,10 @@ float fir_buffer_stereo[FIR_SIZE] = {0}; int fir_index = 0; int channels; +float *last_buffer_val; +float preemphasis_prewarp; +float preemphasis_coefficient; + SNDFILE *inf; @@ -80,7 +84,7 @@ float *alloc_empty_buffer(size_t length) { } -int fm_mpx_open(char *filename, size_t len) { +int fm_mpx_open(char *filename, size_t len, float cutoff_freq, float preemphasis_corner_freq) { length = len; if(filename != NULL) { @@ -114,13 +118,19 @@ int fm_mpx_open(char *filename, size_t len) { printf("%d channels, generating stereo multiplex.\n", channels); } else { printf("1 channel, monophonic operation.\n"); - } - + } + + // Create the preemphasis + last_buffer_val = (float*) malloc(sizeof(float)*channels); + for(int i=0;i. */ -extern int fm_mpx_open(char *filename, size_t len); +extern int fm_mpx_open(char *filename, size_t len, float cutoff_freq, float preemphasis_corner_freq); extern int fm_mpx_get_samples(float *mpx_buffer); extern int fm_mpx_close(); \ No newline at end of file diff --git a/src/pi_fm_rds.c b/src/pi_fm_rds.c index 7423869..0fce32b 100644 --- a/src/pi_fm_rds.c +++ b/src/pi_fm_rds.c @@ -197,7 +197,6 @@ // (broadcast radio) and about 3.5 for NBFM (walkie-talkie style radio) #define DEVIATION 25.0 - typedef struct { uint32_t info, src, dst, length, stride, next, pad[2]; @@ -317,7 +316,7 @@ map_peripheral(uint32_t base, uint32_t len) #define DATA_SIZE 5000 -int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, float ppm, char *control_pipe) { +int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, float ppm, char *control_pipe, float cutoff, float preemphasis_cutoff) { // Catch all signals possible - it is vital we kill the DMA engine // on process exit! for (int i = 0; i < 64; i++) { @@ -452,7 +451,7 @@ int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, int data_index = 0; // Initialize the baseband generator - if(fm_mpx_open(audio_file, DATA_SIZE) < 0) return 1; + if(fm_mpx_open(audio_file, DATA_SIZE, cutoff, preemphasis_cutoff) < 0) return 1; // Initialize the RDS modulator char myps[9] = {0}; @@ -543,6 +542,11 @@ int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, return 0; } +#define PREEMPHASIS_EU 3185 +#define PREEMPHASIS_US 2120 + +#define CUTOFF_COMPLIANT 15000 +#define CUTOFF_QUALITY 22050 int main(int argc, char **argv) { char *audio_file = NULL; @@ -552,6 +556,8 @@ int main(int argc, char **argv) { char *rt = "PiFmRds: live FM-RDS transmission from the RaspberryPi"; uint16_t pi = 0x1234; float ppm = 0; + float cutoff = CUTOFF_COMPLIANT; + float preemphasis_cutoff = PREEMPHASIS_US; // Parse command-line arguments @@ -584,6 +590,26 @@ int main(int argc, char **argv) { } else if(strcmp("-ctl", arg)==0 && param != NULL) { i++; control_pipe = param; + } else if(strcmp("-preemph", arg)==0 && param != NULL) { + i++; + if(strcmp("eu", param)==0) { + preemphasis_cutoff = PREEMPHASIS_EU; + } else if(strcmp("us", param)==0) { + preemphasis_cutoff = PREEMPHASIS_US; + } + else { + preemphasis_cutoff = atof(param); + } + } else if(strcmp("-cutoff", arg)==0 && param != NULL) { + i++; + if(strcmp("compliant", param)==0) { + cutoff = CUTOFF_COMPLIANT; + } else if(strcmp("quality", param)==0) { + cutoff = CUTOFF_QUALITY; + } + else { + cutoff = atof(param); + } } else { fatal("Unrecognised argument: %s.\n" "Syntax: pi_fm_rds [-freq freq] [-audio file] [-ppm ppm_error] [-pi pi_code]\n" @@ -591,7 +617,7 @@ int main(int argc, char **argv) { } } - int errcode = tx(carrier_freq, audio_file, pi, ps, rt, ppm, control_pipe); + int errcode = tx(carrier_freq, audio_file, pi, ps, rt, ppm, control_pipe, cutoff, preemphasis_cutoff); terminate(errcode); }