mirror of
https://github.com/jfdelnero/rf-tools.git
synced 2024-11-26 21:58:39 -05:00
Initial commit : A broadcast FM Stereo modulator.
This commit is contained in:
commit
94f026bfaf
68
build/Makefile
Normal file
68
build/Makefile
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
CC=gcc
|
||||||
|
|
||||||
|
UNAME := $(shell uname)
|
||||||
|
|
||||||
|
DEBUG ?= 0
|
||||||
|
|
||||||
|
ifeq ($(DEBUG), 1)
|
||||||
|
CFLAGS=-O0 $(INCLUDES) -Wall -g -DDEBUG -I ../src/common/
|
||||||
|
LDFLAGS= -lc -lm -ldl -lpthread -lasan
|
||||||
|
else
|
||||||
|
CFLAGS=-O3 $(INCLUDES) -Wall -I ../src/common/
|
||||||
|
LDFLAGS= -lc -lm -ldl -s
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(UNAME), Darwin)
|
||||||
|
CFLAGS += -arch x86_64 -mmacosx-version-min=10.9
|
||||||
|
LDFLAGS += -arch x86_64 -mmacosx-version-min=10.9
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(UNAME), Linux)
|
||||||
|
LDFLAGS += -Wl,-rpath=.
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
||||||
|
endif
|
||||||
|
|
||||||
|
EXEC=broadcast_fm
|
||||||
|
|
||||||
|
all: $(EXEC)
|
||||||
|
|
||||||
|
broadcast_fm: broadcast_fm.o wave.o modulator.o FIR_Audio_Filter_Filter.o FM_Baseband_Filter.o AudioPreemphasis_Filter.o hxcmod.o rand_gen.o
|
||||||
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
broadcast_fm.o: ../src/broadcast_fm/broadcast_fm.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
utils.o: ../src/common/utils.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
wave.o: ../src/common/wave.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
modulator.o: ../src/common/modulator.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
FIR_Audio_Filter_Filter.o: ../src/broadcast_fm/fir_filters/FIR_Audio_Filter_Filter.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
FM_Baseband_Filter.o: ../src/broadcast_fm/fir_filters/FM_Baseband_Filter.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
AudioPreemphasis_Filter.o: ../src/broadcast_fm/fir_filters/AudioPreemphasis_Filter.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
hxcmod.o: ../src/common/hxcmod/hxcmod.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
rand_gen.o: ../src/common/rand_gen.c
|
||||||
|
$(CC) -o $@ -c $< $(CFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o
|
||||||
|
rm -rf *.so
|
||||||
|
|
||||||
|
mrproper: clean
|
||||||
|
rm -rf $(EXEC)
|
||||||
|
|
||||||
|
.PHONY: clean mrproper
|
11
readme
Normal file
11
readme
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
rf-tools : Radio frequency tools and modulators
|
||||||
|
|
||||||
|
Disclaimer / Legal warning : Radio spectrum and the law
|
||||||
|
|
||||||
|
In most / all countries the use of any radio transmitting device is required to be
|
||||||
|
either licensed or specifically exempted from licensing under the local regulator.
|
||||||
|
Other than as used in accordance with a licence (or exemption), the use of radio
|
||||||
|
equipment is illegal.
|
||||||
|
|
||||||
|
So take care to limit the emitting range and power when testing these softwares !
|
||||||
|
|
525
src/broadcast_fm/broadcast_fm.c
Normal file
525
src/broadcast_fm/broadcast_fm.c
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : broadcast_fm.c
|
||||||
|
// Contains: a broadcast FM Stereo modulator
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disclaimer / Legal warning : Radio spectrum and the law
|
||||||
|
//
|
||||||
|
// In most countries the use of any radio transmitting device is required to be
|
||||||
|
// either licensed or specifically exempted from licensing under the local regulator.
|
||||||
|
// Other than as used in accordance with a licence (or exemption),
|
||||||
|
// the use of radio equipment is illegal.
|
||||||
|
//
|
||||||
|
// So take care to limit the emitting range and power when testing this software !
|
||||||
|
//
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
// Example from the FCC (United states) :
|
||||||
|
//
|
||||||
|
// Part 15 Devices
|
||||||
|
//
|
||||||
|
// Unlicensed operation on the AM and FM radio broadcast bands is permitted for
|
||||||
|
// some extremely low powered devices covered under Part 15 of the FCC's rules.
|
||||||
|
// On FM frequencies, these devices are limited to an effective service range
|
||||||
|
// of approximately 200 feet (61 meters).
|
||||||
|
// See 47 CFR (Code of Federal Regulations) Section 15.239, and the July 24,
|
||||||
|
// 1991 Public Notice (still in effect).
|
||||||
|
//
|
||||||
|
// On the AM broadcast band, these devices are limited to an effective service
|
||||||
|
// range of approximately 200 feet (61 meters). See 47 CFR Sections 15.207,
|
||||||
|
// 15.209, 15.219, and 15.221. These devices must accept any interference
|
||||||
|
// caused by any other operation, which may further limit the effective service
|
||||||
|
// range.
|
||||||
|
//
|
||||||
|
// For more information on Part 15 devices, please see OET Bulletin No. 63
|
||||||
|
// ("Understanding the FCC Regulations for Low-Power, Non-Licensed Transmitters").
|
||||||
|
// Questions not answered by this Bulletin can be directed to the FCC's Office
|
||||||
|
// of Engineering and Technology, Customer Service Branch, at the Columbia,
|
||||||
|
// Maryland office, phone (301) 362 - 3000.
|
||||||
|
//
|
||||||
|
// [...]
|
||||||
|
//
|
||||||
|
// Penalties for Operation Without A Permit or License
|
||||||
|
//
|
||||||
|
// The Commission considers unauthorized broadcast operation to be a serious matter.
|
||||||
|
// Presently, the maximum penalty for operating an unlicensed or "pirate" broadcast
|
||||||
|
// station (one which is not permitted under Part 15 or is not a Carrier Current
|
||||||
|
// Station or Campus Radio Station) is set at $10,000 for a single violation or a
|
||||||
|
// single day of operation, up to a total maximum amount of $75,000.
|
||||||
|
//
|
||||||
|
// Adjustments may be made upwards or downwards depending on the circumstances
|
||||||
|
// involved. Equipment used for an unauthorized operation may also be confiscated.
|
||||||
|
// There are also criminal penalties (fine and/or imprisonment) for
|
||||||
|
// "willfully and knowingly" operating a radio station without a license.
|
||||||
|
// DON'T DO IT!
|
||||||
|
//
|
||||||
|
// More at : https://www.fcc.gov/media/radio/low-power-radio-general-information
|
||||||
|
//
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//
|
||||||
|
// Broadcast FM subcarriers
|
||||||
|
//
|
||||||
|
// ________ Stereo L - R modulation
|
||||||
|
// / \ 38KHz DSB-SC
|
||||||
|
// / \ _______ _______
|
||||||
|
// / MONO \ Pilot / \ / \ RDS
|
||||||
|
// / L + R \ | / \ / \ _ _
|
||||||
|
// / \__|__/ \/ \__/ \/ \___
|
||||||
|
//30Hz 15Khz | | | | |
|
||||||
|
// | | | | 57KHz 5%
|
||||||
|
// 19KHz 23KHz 38KHz 53KHz
|
||||||
|
// 10%
|
||||||
|
//
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Current software design :
|
||||||
|
//
|
||||||
|
// Mod player / Left Audio -> Preemphasis (FIR) -> \ / -> Left + Right -> 15KHz low pass (FIR) -------------------------------|
|
||||||
|
// Sound \/ |
|
||||||
|
// generator /\ |
|
||||||
|
// \ Right Audio -> Preemphasis (FIR) -> / \ -> Left - Right -> 15KHz low pass (FIR) |
|
||||||
|
// | |
|
||||||
|
// Sample | Sample Rate at 200KHz V |
|
||||||
|
// Rate at | |MUL| (38KHz DSB-SC modulated)-> + ----> I+Q Modulator --> RF hardware transceiver
|
||||||
|
// 50KHz | ^ | (2MHz sample rate)
|
||||||
|
// | | |
|
||||||
|
// | 38KHz Osc |
|
||||||
|
// | (|) (These oscillators |
|
||||||
|
// | (|) must be kept in phase) |
|
||||||
|
// 19KHz Pilot Osc ------------------|
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "wave.h"
|
||||||
|
|
||||||
|
#include "modulator.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include "fir_filters/FIR_Audio_Filter_Filter.h"
|
||||||
|
#include "fir_filters/AudioPreemphasis_Filter.h"
|
||||||
|
|
||||||
|
#include "hxcmod/hxcmod.h"
|
||||||
|
|
||||||
|
#define IQ_SAMPLE_RATE 2000000
|
||||||
|
#define SUBCARRIERS_SAMPLE_RATE 200000
|
||||||
|
|
||||||
|
#define IF_FREQ 0
|
||||||
|
|
||||||
|
#define BUFFER_SAMPLES_SIZE (1024*8)
|
||||||
|
|
||||||
|
#define printf(fmt...) do { \
|
||||||
|
if(!stdoutmode) \
|
||||||
|
fprintf(stdout, fmt); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int stdoutmode;
|
||||||
|
|
||||||
|
int isOption(int argc, char* argv[],char * paramtosearch,char * argtoparam)
|
||||||
|
{
|
||||||
|
int param=1;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
char option[512];
|
||||||
|
|
||||||
|
memset(option,0,512);
|
||||||
|
while(param<=argc)
|
||||||
|
{
|
||||||
|
if(argv[param])
|
||||||
|
{
|
||||||
|
if(argv[param][0]=='-')
|
||||||
|
{
|
||||||
|
memset(option,0,512);
|
||||||
|
|
||||||
|
j=0;
|
||||||
|
i=1;
|
||||||
|
while( argv[param][i] && argv[param][i]!=':')
|
||||||
|
{
|
||||||
|
option[j]=argv[param][i];
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !strcmp(option,paramtosearch) )
|
||||||
|
{
|
||||||
|
if(argtoparam)
|
||||||
|
{
|
||||||
|
if(argv[param][i]==':')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
j=0;
|
||||||
|
while( argv[param][i] )
|
||||||
|
{
|
||||||
|
argtoparam[j]=argv[param][i];
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
argtoparam[j]=0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printhelp(char* argv[])
|
||||||
|
{
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -stdout \t\t\t: IQ stream send to stdout\n");
|
||||||
|
printf(" -mono \t\t\t: Mono FM mode\n");
|
||||||
|
printf(" -mod_file:[MODFILE.MOD]\t: MOD music file to play\n");
|
||||||
|
printf(" -generate \t\t\t: Generate the IQ stream\n");
|
||||||
|
printf(" -help \t\t\t: This help\n\n");
|
||||||
|
printf("Example : 100.9MHz broadcasting with an hackrf\n./broadcast_fm -generate -stdout -mod_file:meo-sleeping_waste.mod | hackrf_transfer -f 100900000 -t - -x 47 -a 1 -s 2000000\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
unsigned int i,j,k;
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
char filename[512];
|
||||||
|
|
||||||
|
int mod_data_size = 0;
|
||||||
|
unsigned char * mod_data;
|
||||||
|
|
||||||
|
wave_io * wave1,*wave2;
|
||||||
|
|
||||||
|
double audio_sample_l;
|
||||||
|
double audio_sample_r;
|
||||||
|
double audio_sample_final;
|
||||||
|
double audio_sample_r_car;
|
||||||
|
double pilot_sample;
|
||||||
|
double balance_sample;
|
||||||
|
double fm_mod;
|
||||||
|
|
||||||
|
double old_freq,interpolation_step;
|
||||||
|
double leftplusright_audio,leftminusright_audio;
|
||||||
|
|
||||||
|
modcontext modctx;
|
||||||
|
|
||||||
|
FIR_Audio_Filter_Filter leftplusright_audio_filter,leftminusright_audio_filter;
|
||||||
|
AudioPreemphasis_Filter preamphasis_left_filter,preamphasis_right_filter;
|
||||||
|
//FM_Baseband_Filter fmband_filter;
|
||||||
|
|
||||||
|
iq_wave_gen iqgen;
|
||||||
|
|
||||||
|
wave_gen audio_l_gen;
|
||||||
|
wave_gen audio_r_gen;
|
||||||
|
|
||||||
|
wave_gen balance_ctrl;
|
||||||
|
|
||||||
|
wave_gen audiow_stereo38KHz_gen;
|
||||||
|
wave_gen stereo_pilot_gen;
|
||||||
|
|
||||||
|
uint16_t iq_wave_buf[ BUFFER_SAMPLES_SIZE * (IQ_SAMPLE_RATE/SUBCARRIERS_SAMPLE_RATE)];
|
||||||
|
int16_t mod_wave_buf[(BUFFER_SAMPLES_SIZE*2)/4];
|
||||||
|
int16_t subcarriers_dbg_wave_buf[BUFFER_SAMPLES_SIZE];
|
||||||
|
double subcarriers_float_wave_buf[BUFFER_SAMPLES_SIZE];
|
||||||
|
|
||||||
|
int monomode;
|
||||||
|
|
||||||
|
stdoutmode = 0;
|
||||||
|
monomode = 0;
|
||||||
|
|
||||||
|
if(isOption(argc,argv,"stdout",NULL)>0)
|
||||||
|
{
|
||||||
|
stdoutmode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stdoutmode)
|
||||||
|
{
|
||||||
|
printf("broadcast_fm v0.0.1.1\n");
|
||||||
|
printf("Copyright (C) 2022 Jean-Francois DEL NERO\n");
|
||||||
|
printf("This program comes with ABSOLUTELY NO WARRANTY\n");
|
||||||
|
printf("This is free software, and you are welcome to redistribute it\n");
|
||||||
|
printf("under certain conditions;\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// help option...
|
||||||
|
if(isOption(argc,argv,"help",0)>0)
|
||||||
|
{
|
||||||
|
printhelp(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(filename,0,sizeof(filename));
|
||||||
|
// Input file name option
|
||||||
|
if(isOption(argc,argv,"mod_file",(char*)&filename)>0)
|
||||||
|
{
|
||||||
|
printf("Input file : %s\n",filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isOption(argc,argv,"mono",NULL)>0)
|
||||||
|
{
|
||||||
|
monomode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isOption(argc,argv,"generate",0)>0)
|
||||||
|
{
|
||||||
|
// Init the .mod player and load the mod file.
|
||||||
|
hxcmod_init(&modctx);
|
||||||
|
|
||||||
|
hxcmod_setcfg(&modctx, SUBCARRIERS_SAMPLE_RATE/4, 1, 0); //(50000 samples/s, 25000 Hz)
|
||||||
|
|
||||||
|
mod_data_size = 0;
|
||||||
|
mod_data = NULL;
|
||||||
|
f = fopen(filename,"r");
|
||||||
|
if(f)
|
||||||
|
{
|
||||||
|
fseek(f,0,SEEK_END);
|
||||||
|
mod_data_size = ftell(f);
|
||||||
|
fseek(f,0,SEEK_SET);
|
||||||
|
|
||||||
|
mod_data = malloc(mod_data_size);
|
||||||
|
|
||||||
|
if(fread(mod_data,mod_data_size,1,f) == 1)
|
||||||
|
{
|
||||||
|
hxcmod_load(&modctx, mod_data, mod_data_size );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(mod_data);
|
||||||
|
mod_data = NULL;
|
||||||
|
mod_data_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init all filters
|
||||||
|
AudioPreemphasis_Filter_init(&preamphasis_left_filter);
|
||||||
|
AudioPreemphasis_Filter_init(&preamphasis_right_filter);
|
||||||
|
FIR_Audio_Filter_Filter_init(&leftplusright_audio_filter);
|
||||||
|
FIR_Audio_Filter_Filter_init(&leftminusright_audio_filter);
|
||||||
|
|
||||||
|
//FM_Baseband_Filter_init(&fmband_filter);
|
||||||
|
|
||||||
|
// Init oscillators
|
||||||
|
|
||||||
|
// Left and Right audio freq (used if no .mod music file)
|
||||||
|
audio_l_gen.phase = 0;
|
||||||
|
audio_l_gen.Frequency = 700;
|
||||||
|
audio_l_gen.Amplitude = 22.5;
|
||||||
|
audio_l_gen.sample_rate = SUBCARRIERS_SAMPLE_RATE;
|
||||||
|
|
||||||
|
audio_r_gen.phase = 0;
|
||||||
|
audio_r_gen.Frequency = 1000;
|
||||||
|
audio_r_gen.Amplitude = 22.5;
|
||||||
|
audio_r_gen.sample_rate = SUBCARRIERS_SAMPLE_RATE;
|
||||||
|
|
||||||
|
// Left <> Right balance LFO (used if no .mod music file)
|
||||||
|
balance_ctrl.phase = 0;
|
||||||
|
balance_ctrl.Frequency = 1.2;
|
||||||
|
balance_ctrl.Amplitude = 12.5;
|
||||||
|
balance_ctrl.sample_rate = SUBCARRIERS_SAMPLE_RATE;
|
||||||
|
|
||||||
|
// Stereo Pilot
|
||||||
|
stereo_pilot_gen.phase = 0;
|
||||||
|
stereo_pilot_gen.Frequency = 19000;
|
||||||
|
stereo_pilot_gen.Amplitude = 10.0; // 10%
|
||||||
|
stereo_pilot_gen.sample_rate = SUBCARRIERS_SAMPLE_RATE;
|
||||||
|
|
||||||
|
// 38KHz +/- 15KHz stereo modulator
|
||||||
|
audiow_stereo38KHz_gen.phase = 0;
|
||||||
|
audiow_stereo38KHz_gen.Frequency = 38000;
|
||||||
|
audiow_stereo38KHz_gen.Amplitude = 1;
|
||||||
|
audiow_stereo38KHz_gen.sample_rate = SUBCARRIERS_SAMPLE_RATE;
|
||||||
|
|
||||||
|
// IQ Modulator
|
||||||
|
iqgen.phase = 0;
|
||||||
|
iqgen.Frequency = IF_FREQ;
|
||||||
|
iqgen.Amplitude = 127;
|
||||||
|
iqgen.sample_rate = IQ_SAMPLE_RATE;
|
||||||
|
|
||||||
|
audio_sample_r = 0;
|
||||||
|
audio_sample_l = 0;
|
||||||
|
|
||||||
|
if(stdoutmode)
|
||||||
|
{
|
||||||
|
// stdout / stream mode : IQ are outputed to the stdout -> use a pipe to hackrf_transfer
|
||||||
|
wave1 = create_wave(NULL,iqgen.sample_rate,WAVE_FILE_FORMAT_RAW_8BITS_IQ);
|
||||||
|
wave2 = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// file mode : create iq + wav files
|
||||||
|
wave1 = create_wave("broadcast_fm.iq",iqgen.sample_rate,WAVE_FILE_FORMAT_RAW_8BITS_IQ);
|
||||||
|
wave2 = create_wave("broadcast_fm.wav",SUBCARRIERS_SAMPLE_RATE,WAVE_FILE_FORMAT_WAV_16BITS_MONO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wave1)
|
||||||
|
{
|
||||||
|
old_freq = IF_FREQ;
|
||||||
|
|
||||||
|
// Main loop...
|
||||||
|
for(i=0;(i<1024) || stdoutmode ;i++)
|
||||||
|
{
|
||||||
|
printf("%d / %d...\n",i,1024);
|
||||||
|
|
||||||
|
hxcmod_fillbuffer( &modctx, (msample*)&mod_wave_buf, BUFFER_SAMPLES_SIZE/4, NULL );
|
||||||
|
|
||||||
|
for(j=0;j<BUFFER_SAMPLES_SIZE;j++)
|
||||||
|
{
|
||||||
|
if(!mod_data_size)
|
||||||
|
{
|
||||||
|
// No music module loaded -> Play left/right tones.
|
||||||
|
|
||||||
|
// Dynamically set volumes for left and right oscillators.
|
||||||
|
balance_sample = f_get_next_sample(&balance_ctrl);
|
||||||
|
|
||||||
|
audio_l_gen.Amplitude = balance_sample;
|
||||||
|
audio_r_gen.Amplitude = -balance_sample;
|
||||||
|
if(audio_r_gen.Amplitude < 0) audio_r_gen.Amplitude = 0;
|
||||||
|
if(audio_l_gen.Amplitude < 0) audio_l_gen.Amplitude = 0;
|
||||||
|
|
||||||
|
// Get the left and right samples.
|
||||||
|
audio_sample_l = f_get_next_sample(&audio_l_gen);
|
||||||
|
audio_sample_r = f_get_next_sample(&audio_r_gen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(j&3))
|
||||||
|
{
|
||||||
|
audio_sample_l = ((double)((mod_wave_buf[((j/4)*2)]) / (double)32768)) * (double)22.5;
|
||||||
|
audio_sample_r = ((double)((mod_wave_buf[((j/4)*2)+1]) / (double)32768)) * (double)22.5;
|
||||||
|
|
||||||
|
// Left & Right Preamphasis filter.
|
||||||
|
AudioPreemphasis_Filter_put(&preamphasis_left_filter, audio_sample_l );
|
||||||
|
audio_sample_l = AudioPreemphasis_Filter_get(&preamphasis_left_filter);
|
||||||
|
|
||||||
|
AudioPreemphasis_Filter_put(&preamphasis_right_filter, audio_sample_r );
|
||||||
|
audio_sample_r = AudioPreemphasis_Filter_get(&preamphasis_right_filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main / Mono channel : Left + Right
|
||||||
|
leftplusright_audio = audio_sample_l + audio_sample_r;
|
||||||
|
|
||||||
|
// 0KHz<->15KHz pass band/low pass filter
|
||||||
|
FIR_Audio_Filter_Filter_put(&leftplusright_audio_filter, leftplusright_audio);
|
||||||
|
leftplusright_audio = FIR_Audio_Filter_Filter_get(&leftplusright_audio_filter);
|
||||||
|
|
||||||
|
if(!monomode)
|
||||||
|
{
|
||||||
|
// Stereo Channel : Left - Right
|
||||||
|
leftminusright_audio = audio_sample_l - audio_sample_r;
|
||||||
|
|
||||||
|
// 0KHz<->15KHz pass band/low pass filter
|
||||||
|
FIR_Audio_Filter_Filter_put(&leftminusright_audio_filter, leftminusright_audio);
|
||||||
|
leftminusright_audio = FIR_Audio_Filter_Filter_get(&leftminusright_audio_filter);
|
||||||
|
|
||||||
|
// Keep the 18KHz pilot and the 38KHz clock in phase :
|
||||||
|
audiow_stereo38KHz_gen.phase = (stereo_pilot_gen.phase * 2) + PI/2;
|
||||||
|
|
||||||
|
// 38KHz DSB-SC (Double-sideband suppressed-carrier) modulation
|
||||||
|
audio_sample_r_car = f_get_next_sample(&audiow_stereo38KHz_gen); // Get the 38KHz carrier
|
||||||
|
audio_sample_r_car = (audio_sample_r_car * leftminusright_audio ); // And multiply it with the left - right sample.
|
||||||
|
|
||||||
|
// 18KHz pilot
|
||||||
|
pilot_sample = f_get_next_sample(&stereo_pilot_gen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Mono : No pilot nor 38KHz modulation...
|
||||||
|
audio_sample_r_car = 0;
|
||||||
|
pilot_sample = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mix all signals sources :
|
||||||
|
// 45% 45% 10%
|
||||||
|
audio_sample_final = ((leftplusright_audio) + audio_sample_r_car + pilot_sample);
|
||||||
|
|
||||||
|
// Main carrier frequency modulation : +/- 75KHz
|
||||||
|
fm_mod = ((audio_sample_final / (double)(100.0)) * (double)(75000));
|
||||||
|
|
||||||
|
// Low pass filter <100KHz
|
||||||
|
// Note : Not needed here since we use a 200KHz sample rate.
|
||||||
|
//FM_Baseband_Filter_put(&fmband_filter, fm_mod );
|
||||||
|
//fm_mod = FM_Baseband_Filter_get(&fmband_filter);
|
||||||
|
|
||||||
|
subcarriers_dbg_wave_buf[j] = fm_mod;
|
||||||
|
subcarriers_float_wave_buf[j] = fm_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub carriers sample rate to carrier IQ rate modulation + resampling
|
||||||
|
for(j=0;j<BUFFER_SAMPLES_SIZE;j++)
|
||||||
|
{
|
||||||
|
// linear interpolation. (TODO ?: Cubic interpolation)
|
||||||
|
interpolation_step = (subcarriers_float_wave_buf[j] - old_freq) / (double)(IQ_SAMPLE_RATE/SUBCARRIERS_SAMPLE_RATE);
|
||||||
|
|
||||||
|
for(k=0;k<(IQ_SAMPLE_RATE/SUBCARRIERS_SAMPLE_RATE);k++)
|
||||||
|
{
|
||||||
|
old_freq += interpolation_step;
|
||||||
|
|
||||||
|
iqgen.Frequency = ((double)IF_FREQ + old_freq);
|
||||||
|
iq_wave_buf[(j*(IQ_SAMPLE_RATE/SUBCARRIERS_SAMPLE_RATE))+k] = get_next_iq(&iqgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
old_freq = subcarriers_float_wave_buf[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
write_wave(wave1, &iq_wave_buf,BUFFER_SAMPLES_SIZE*(IQ_SAMPLE_RATE/SUBCARRIERS_SAMPLE_RATE));
|
||||||
|
write_wave(wave2, &subcarriers_dbg_wave_buf,BUFFER_SAMPLES_SIZE);
|
||||||
|
}
|
||||||
|
close_wave(wave1);
|
||||||
|
close_wave(wave2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (isOption(argc,argv,"help",0)<=0) &&
|
||||||
|
(isOption(argc,argv,"generate",0)<=0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
printhelp(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
30
src/broadcast_fm/fir_filters/AudioPreemphasis_Filter.c
Normal file
30
src/broadcast_fm/fir_filters/AudioPreemphasis_Filter.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include "AudioPreemphasis_Filter.h"
|
||||||
|
|
||||||
|
static double filter_taps[AUDIOPREEMPHASIS_FILTER_TAP_NUM] = {
|
||||||
|
-2.676917973553303,
|
||||||
|
6.337642794858812,
|
||||||
|
-2.676917973553303
|
||||||
|
};
|
||||||
|
|
||||||
|
void AudioPreemphasis_Filter_init(AudioPreemphasis_Filter* f) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < AUDIOPREEMPHASIS_FILTER_TAP_NUM; ++i)
|
||||||
|
f->history[i] = 0;
|
||||||
|
f->last_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPreemphasis_Filter_put(AudioPreemphasis_Filter* f, double input) {
|
||||||
|
f->history[f->last_index++] = input;
|
||||||
|
if(f->last_index == AUDIOPREEMPHASIS_FILTER_TAP_NUM)
|
||||||
|
f->last_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double AudioPreemphasis_Filter_get(AudioPreemphasis_Filter* f) {
|
||||||
|
double acc = 0;
|
||||||
|
int index = f->last_index, i;
|
||||||
|
for(i = 0; i < AUDIOPREEMPHASIS_FILTER_TAP_NUM; ++i) {
|
||||||
|
index = index != 0 ? index-1 : AUDIOPREEMPHASIS_FILTER_TAP_NUM-1;
|
||||||
|
acc += f->history[index] * filter_taps[i];
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}
|
35
src/broadcast_fm/fir_filters/AudioPreemphasis_Filter.h
Normal file
35
src/broadcast_fm/fir_filters/AudioPreemphasis_Filter.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef AUDIOPREEMPHASIS_FILTER_H_
|
||||||
|
#define AUDIOPREEMPHASIS_FILTER_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
FIR filter designed with
|
||||||
|
http://t-filter.appspot.com
|
||||||
|
|
||||||
|
sampling frequency: 50000 Hz
|
||||||
|
|
||||||
|
* 0 Hz - 2100 Hz
|
||||||
|
gain = 1
|
||||||
|
desired ripple = 5 dB
|
||||||
|
actual ripple = 1.2624293131559894 dB
|
||||||
|
|
||||||
|
* 15500 Hz - 25000 Hz
|
||||||
|
gain = 6.309573444801933
|
||||||
|
desired ripple = 5 dB
|
||||||
|
actual ripple = 2.740064802010604 dB
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AUDIOPREEMPHASIS_FILTER_TAP_NUM 3
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double history[AUDIOPREEMPHASIS_FILTER_TAP_NUM];
|
||||||
|
unsigned int last_index;
|
||||||
|
} AudioPreemphasis_Filter;
|
||||||
|
|
||||||
|
void AudioPreemphasis_Filter_init(AudioPreemphasis_Filter* f);
|
||||||
|
void AudioPreemphasis_Filter_put(AudioPreemphasis_Filter* f, double input);
|
||||||
|
double AudioPreemphasis_Filter_get(AudioPreemphasis_Filter* f);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
152
src/broadcast_fm/fir_filters/FIR_Audio_Filter_Filter.c
Normal file
152
src/broadcast_fm/fir_filters/FIR_Audio_Filter_Filter.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include "FIR_Audio_Filter_Filter.h"
|
||||||
|
|
||||||
|
static double filter_taps[FIR_AUDIO_FILTER_FILTER_TAP_NUM] = {
|
||||||
|
0.005517301037304242,
|
||||||
|
0.010958468006496662,
|
||||||
|
0.010240455922518009,
|
||||||
|
0.01626919575760614,
|
||||||
|
0.017121566138134488,
|
||||||
|
0.019559785776548867,
|
||||||
|
0.018573985808748823,
|
||||||
|
0.016981674306998703,
|
||||||
|
0.013027824505458897,
|
||||||
|
0.008348299295171996,
|
||||||
|
0.002827934347197235,
|
||||||
|
-0.0022439756999176066,
|
||||||
|
-0.006402028253938463,
|
||||||
|
-0.008814800382330594,
|
||||||
|
-0.009267566652943171,
|
||||||
|
-0.007703207526723216,
|
||||||
|
-0.004562291988505165,
|
||||||
|
-0.0005232995432083925,
|
||||||
|
0.003518575437801644,
|
||||||
|
0.006694025550492667,
|
||||||
|
0.008294079489543669,
|
||||||
|
0.007965160640712026,
|
||||||
|
0.005755920521670115,
|
||||||
|
0.0021526778614508585,
|
||||||
|
-0.0020452123559512488,
|
||||||
|
-0.005875787341622662,
|
||||||
|
-0.008425796705843449,
|
||||||
|
-0.009052315787298352,
|
||||||
|
-0.00752225339131066,
|
||||||
|
-0.0040990782652213,
|
||||||
|
0.00049750332784811,
|
||||||
|
0.005234144776188673,
|
||||||
|
0.008990696285244222,
|
||||||
|
0.010798308794869566,
|
||||||
|
0.010105847532439045,
|
||||||
|
0.006897132667607324,
|
||||||
|
0.0017653188321013905,
|
||||||
|
-0.00420373081909947,
|
||||||
|
-0.00964286796105942,
|
||||||
|
-0.013192556860158036,
|
||||||
|
-0.013826393925481531,
|
||||||
|
-0.011121337171052629,
|
||||||
|
-0.005396493245103629,
|
||||||
|
0.0022726920185823602,
|
||||||
|
0.010240805979570002,
|
||||||
|
0.016615084025158867,
|
||||||
|
0.019654280140049052,
|
||||||
|
0.018177759921499358,
|
||||||
|
0.011915646666813001,
|
||||||
|
0.0016581423845507999,
|
||||||
|
-0.010757223751418863,
|
||||||
|
-0.02270805003461664,
|
||||||
|
-0.03121367797048097,
|
||||||
|
-0.033501256492323245,
|
||||||
|
-0.027529898309997605,
|
||||||
|
-0.012463160702206726,
|
||||||
|
0.011056274270822274,
|
||||||
|
0.04090736333522399,
|
||||||
|
0.07374003152391906,
|
||||||
|
0.10546517736325783,
|
||||||
|
0.131881590198464,
|
||||||
|
0.1493758864385702,
|
||||||
|
0.1554926121172843,
|
||||||
|
0.1493758864385702,
|
||||||
|
0.131881590198464,
|
||||||
|
0.10546517736325783,
|
||||||
|
0.07374003152391906,
|
||||||
|
0.04090736333522399,
|
||||||
|
0.011056274270822274,
|
||||||
|
-0.012463160702206726,
|
||||||
|
-0.027529898309997605,
|
||||||
|
-0.033501256492323245,
|
||||||
|
-0.03121367797048097,
|
||||||
|
-0.02270805003461664,
|
||||||
|
-0.010757223751418863,
|
||||||
|
0.0016581423845507999,
|
||||||
|
0.011915646666813001,
|
||||||
|
0.018177759921499358,
|
||||||
|
0.019654280140049052,
|
||||||
|
0.016615084025158867,
|
||||||
|
0.010240805979570002,
|
||||||
|
0.0022726920185823602,
|
||||||
|
-0.005396493245103629,
|
||||||
|
-0.011121337171052629,
|
||||||
|
-0.013826393925481531,
|
||||||
|
-0.013192556860158036,
|
||||||
|
-0.00964286796105942,
|
||||||
|
-0.00420373081909947,
|
||||||
|
0.0017653188321013905,
|
||||||
|
0.006897132667607324,
|
||||||
|
0.010105847532439045,
|
||||||
|
0.010798308794869566,
|
||||||
|
0.008990696285244222,
|
||||||
|
0.005234144776188673,
|
||||||
|
0.00049750332784811,
|
||||||
|
-0.0040990782652213,
|
||||||
|
-0.00752225339131066,
|
||||||
|
-0.009052315787298352,
|
||||||
|
-0.008425796705843449,
|
||||||
|
-0.005875787341622662,
|
||||||
|
-0.0020452123559512488,
|
||||||
|
0.0021526778614508585,
|
||||||
|
0.005755920521670115,
|
||||||
|
0.007965160640712026,
|
||||||
|
0.008294079489543669,
|
||||||
|
0.006694025550492667,
|
||||||
|
0.003518575437801644,
|
||||||
|
-0.0005232995432083925,
|
||||||
|
-0.004562291988505165,
|
||||||
|
-0.007703207526723216,
|
||||||
|
-0.009267566652943171,
|
||||||
|
-0.008814800382330594,
|
||||||
|
-0.006402028253938463,
|
||||||
|
-0.0022439756999176066,
|
||||||
|
0.002827934347197235,
|
||||||
|
0.008348299295171996,
|
||||||
|
0.013027824505458897,
|
||||||
|
0.016981674306998703,
|
||||||
|
0.018573985808748823,
|
||||||
|
0.019559785776548867,
|
||||||
|
0.017121566138134488,
|
||||||
|
0.01626919575760614,
|
||||||
|
0.010240455922518009,
|
||||||
|
0.010958468006496662,
|
||||||
|
0.005517301037304242
|
||||||
|
};
|
||||||
|
|
||||||
|
void FIR_Audio_Filter_Filter_init(FIR_Audio_Filter_Filter* f) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < FIR_AUDIO_FILTER_FILTER_TAP_NUM; ++i)
|
||||||
|
f->history[i] = 0;
|
||||||
|
f->last_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FIR_Audio_Filter_Filter_put(FIR_Audio_Filter_Filter* f, double input) {
|
||||||
|
f->history[f->last_index++] = input;
|
||||||
|
if(f->last_index == FIR_AUDIO_FILTER_FILTER_TAP_NUM)
|
||||||
|
f->last_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double FIR_Audio_Filter_Filter_get(FIR_Audio_Filter_Filter* f) {
|
||||||
|
double acc = 0;
|
||||||
|
int index = f->last_index, i;
|
||||||
|
for(i = 0; i < FIR_AUDIO_FILTER_FILTER_TAP_NUM; ++i) {
|
||||||
|
index = index != 0 ? index-1 : FIR_AUDIO_FILTER_FILTER_TAP_NUM-1;
|
||||||
|
acc += f->history[index] * filter_taps[i];
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}
|
34
src/broadcast_fm/fir_filters/FIR_Audio_Filter_Filter.h
Normal file
34
src/broadcast_fm/fir_filters/FIR_Audio_Filter_Filter.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef FIR_AUDIO_FILTER_FILTER_H_
|
||||||
|
#define FIR_AUDIO_FILTER_FILTER_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
FIR filter designed with
|
||||||
|
http://t-filter.appspot.com
|
||||||
|
|
||||||
|
sampling frequency: 200000 Hz
|
||||||
|
|
||||||
|
* 0 Hz - 15000 Hz
|
||||||
|
gain = 1
|
||||||
|
desired ripple = 5 dB
|
||||||
|
actual ripple = 4.131020865324735 dB
|
||||||
|
|
||||||
|
* 16600 Hz - 100000 Hz
|
||||||
|
gain = 0
|
||||||
|
desired attenuation = -40 dB
|
||||||
|
actual attenuation = -40.090485410010906 dB
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FIR_AUDIO_FILTER_FILTER_TAP_NUM 125
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double history[FIR_AUDIO_FILTER_FILTER_TAP_NUM];
|
||||||
|
unsigned int last_index;
|
||||||
|
} FIR_Audio_Filter_Filter;
|
||||||
|
|
||||||
|
void FIR_Audio_Filter_Filter_init(FIR_Audio_Filter_Filter* f);
|
||||||
|
void FIR_Audio_Filter_Filter_put(FIR_Audio_Filter_Filter* f, double input);
|
||||||
|
double FIR_Audio_Filter_Filter_get(FIR_Audio_Filter_Filter* f);
|
||||||
|
|
||||||
|
#endif
|
683
src/broadcast_fm/fir_filters/FM_Baseband_Filter.c
Normal file
683
src/broadcast_fm/fir_filters/FM_Baseband_Filter.c
Normal file
@ -0,0 +1,683 @@
|
|||||||
|
#include "FM_Baseband_Filter.h"
|
||||||
|
|
||||||
|
static double filter_taps[FM_BASEBAND_FILTER_TAP_NUM] = {
|
||||||
|
-0.006276773743368246,
|
||||||
|
-0.002906124689895695,
|
||||||
|
-0.0034810491402275856,
|
||||||
|
-0.004053348584904465,
|
||||||
|
-0.004602917018038953,
|
||||||
|
-0.00510864933708306,
|
||||||
|
-0.005549178890478986,
|
||||||
|
-0.005903803434753803,
|
||||||
|
-0.006153352756740714,
|
||||||
|
-0.0062810419368997195,
|
||||||
|
-0.006273284055978816,
|
||||||
|
-0.0061205500978807606,
|
||||||
|
-0.005817832832522139,
|
||||||
|
-0.005365157561460779,
|
||||||
|
-0.00476798650929006,
|
||||||
|
-0.00403722847791321,
|
||||||
|
-0.003188871268023831,
|
||||||
|
-0.0022438395226593234,
|
||||||
|
-0.0012271560122908633,
|
||||||
|
-0.00016698144545659763,
|
||||||
|
0.0009061942378719186,
|
||||||
|
0.0019610873421838713,
|
||||||
|
0.0029665219630286475,
|
||||||
|
0.003892678282644405,
|
||||||
|
0.0047125166256176704,
|
||||||
|
0.005402338389433701,
|
||||||
|
0.005943231522926785,
|
||||||
|
0.006321383314346843,
|
||||||
|
0.00652916985473517,
|
||||||
|
0.006565317350605899,
|
||||||
|
0.006435200226996191,
|
||||||
|
0.006150572165634373,
|
||||||
|
0.005729115424630075,
|
||||||
|
0.0051935953163101374,
|
||||||
|
0.004570706217926675,
|
||||||
|
0.0038898729887556515,
|
||||||
|
0.003181825807588361,
|
||||||
|
0.002477679601003533,
|
||||||
|
0.001807325109970609,
|
||||||
|
0.001198808101593799,
|
||||||
|
0.000676466760403685,
|
||||||
|
0.00026038278850552165,
|
||||||
|
-0.00003519485538394603,
|
||||||
|
-0.0002024986474888905,
|
||||||
|
-0.00024019085124103728,
|
||||||
|
-0.00015331390959515178,
|
||||||
|
0.00004791480114281375,
|
||||||
|
0.00034866017633577485,
|
||||||
|
0.0007296960675978035,
|
||||||
|
0.001167933929422274,
|
||||||
|
0.001636917920572586,
|
||||||
|
0.0021085978153374337,
|
||||||
|
0.0025562644079397566,
|
||||||
|
0.0029568799307201055,
|
||||||
|
0.003291074349553435,
|
||||||
|
0.0035414284335566213,
|
||||||
|
0.0036920509207547503,
|
||||||
|
0.00373312207850841,
|
||||||
|
0.003666696471321502,
|
||||||
|
0.003502213813807159,
|
||||||
|
0.00324212650920447,
|
||||||
|
0.0028914904576434483,
|
||||||
|
0.0024934237802220847,
|
||||||
|
0.002043603816320018,
|
||||||
|
0.0015808468393586463,
|
||||||
|
0.001122598250955268,
|
||||||
|
0.0006936436970225945,
|
||||||
|
0.00031496346957593816,
|
||||||
|
0.000004837984574109052,
|
||||||
|
-0.00022232703032059695,
|
||||||
|
-0.0003566665079835044,
|
||||||
|
-0.00039339019608776595,
|
||||||
|
-0.000333110808989004,
|
||||||
|
-0.00018159497394687693,
|
||||||
|
0.00005048775593523694,
|
||||||
|
0.0003481061116814,
|
||||||
|
0.0006927997977343629,
|
||||||
|
0.0010638765819667507,
|
||||||
|
0.0014393167512730105,
|
||||||
|
0.0017971738401020903,
|
||||||
|
0.0021166520909361806,
|
||||||
|
0.0023791019266531147,
|
||||||
|
0.0025693090410960793,
|
||||||
|
0.002675931198702369,
|
||||||
|
0.0026923543124503487,
|
||||||
|
0.0026171805325111786,
|
||||||
|
0.002454031118912115,
|
||||||
|
0.0022116895646837804,
|
||||||
|
0.0019030267726684862,
|
||||||
|
0.0015446566595713781,
|
||||||
|
0.0011557133218574656,
|
||||||
|
0.0007570502661148399,
|
||||||
|
0.00037004878160910566,
|
||||||
|
0.00001556164895794005,
|
||||||
|
-0.0002873259421258282,
|
||||||
|
-0.0005225020827002275,
|
||||||
|
-0.0006778152785331262,
|
||||||
|
-0.0007458291450652108,
|
||||||
|
-0.0007237724027604178,
|
||||||
|
-0.0006139467826508875,
|
||||||
|
-0.0004230530550807403,
|
||||||
|
-0.0001628354231637733,
|
||||||
|
0.00015129060306465846,
|
||||||
|
0.0005003479818101034,
|
||||||
|
0.0008636162701018116,
|
||||||
|
0.0012200029156715312,
|
||||||
|
0.001548740624466772,
|
||||||
|
0.0018306821451188385,
|
||||||
|
0.0020487233738411786,
|
||||||
|
0.0021891204599193454,
|
||||||
|
0.002243244512808436,
|
||||||
|
0.0022077928016267247,
|
||||||
|
0.002084143087394179,
|
||||||
|
0.0018778523547873093,
|
||||||
|
0.0015991122050812935,
|
||||||
|
0.0012633901100129934,
|
||||||
|
0.0008900089027853051,
|
||||||
|
0.0004988789779988034,
|
||||||
|
0.00011015896725885363,
|
||||||
|
-0.0002535400937416474,
|
||||||
|
-0.0005702276065943115,
|
||||||
|
-0.0008248106197065263,
|
||||||
|
-0.0010037105425627479,
|
||||||
|
-0.0010922057096824714,
|
||||||
|
-0.0010918347055704724,
|
||||||
|
-0.0009972609130431105,
|
||||||
|
-0.0008171434769424912,
|
||||||
|
-0.0005602703726361708,
|
||||||
|
-0.00024184631248718984,
|
||||||
|
0.00011989306001557591,
|
||||||
|
0.0005039966417534989,
|
||||||
|
0.0008882139336450031,
|
||||||
|
0.001250150108424033,
|
||||||
|
0.0015684774729692547,
|
||||||
|
0.001824332418711941,
|
||||||
|
0.0020022457010850096,
|
||||||
|
0.0020909788043975276,
|
||||||
|
0.002084241239549793,
|
||||||
|
0.0019812511669580956,
|
||||||
|
0.001786670875323066,
|
||||||
|
0.0015105823732014887,
|
||||||
|
0.0011676956517593336,
|
||||||
|
0.0007765672753843151,
|
||||||
|
0.00035878897793891384,
|
||||||
|
-0.00006253548108123283,
|
||||||
|
-0.0004637552851828441,
|
||||||
|
-0.0008220930819068703,
|
||||||
|
-0.0011170665364279842,
|
||||||
|
-0.001331475322813246,
|
||||||
|
-0.001452868444758477,
|
||||||
|
-0.0014738073952633322,
|
||||||
|
-0.0013925554944245599,
|
||||||
|
-0.001212981144562626,
|
||||||
|
-0.000944644997827479,
|
||||||
|
-0.0006023329394979184,
|
||||||
|
-0.0002053053709292688,
|
||||||
|
0.00022392080409527296,
|
||||||
|
0.0006609144606176251,
|
||||||
|
0.0010805902221096093,
|
||||||
|
0.0014587022318349155,
|
||||||
|
0.0017727389893637477,
|
||||||
|
0.0020038657435381257,
|
||||||
|
0.0021373573333903907,
|
||||||
|
0.0021647196370404324,
|
||||||
|
0.0020828998261889996,
|
||||||
|
0.0018952302758044716,
|
||||||
|
0.0016108477670202955,
|
||||||
|
0.001244407904014974,
|
||||||
|
0.0008161029752255834,
|
||||||
|
0.00034959201045762735,
|
||||||
|
-0.00012940307877066482,
|
||||||
|
-0.0005940260022155878,
|
||||||
|
-0.0010176577556310668,
|
||||||
|
-0.0013754156241168216,
|
||||||
|
-0.0016462249002119438,
|
||||||
|
-0.0018142393477275655,
|
||||||
|
-0.0018687427312488538,
|
||||||
|
-0.0018046936739308204,
|
||||||
|
-0.0016246736311703472,
|
||||||
|
-0.001338448595903364,
|
||||||
|
-0.0009605147153735846,
|
||||||
|
-0.0005108126444730755,
|
||||||
|
-0.00001565838520828236,
|
||||||
|
0.0004975083602194651,
|
||||||
|
0.0010006023914098225,
|
||||||
|
0.001462016316333705,
|
||||||
|
0.001857288190223437,
|
||||||
|
0.0021606030300284607,
|
||||||
|
0.002354435255283183,
|
||||||
|
0.0024253663999272922,
|
||||||
|
0.0023675334058277852,
|
||||||
|
0.002182089414459102,
|
||||||
|
0.0018776951564996795,
|
||||||
|
0.0014698815939004595,
|
||||||
|
0.0009802099743280804,
|
||||||
|
0.00043530470972525385,
|
||||||
|
-0.0001346731858706825,
|
||||||
|
-0.0006976628796186629,
|
||||||
|
-0.0012215159916327684,
|
||||||
|
-0.0016757415624847984,
|
||||||
|
-0.002033429226170653,
|
||||||
|
-0.0022726649592763708,
|
||||||
|
-0.002378134377120082,
|
||||||
|
-0.002341854284500264,
|
||||||
|
-0.0021636093678711237,
|
||||||
|
-0.00185139126645343,
|
||||||
|
-0.0014208790055546586,
|
||||||
|
-0.000894944574293136,
|
||||||
|
-0.0003023080541089114,
|
||||||
|
0.00032421742432794986,
|
||||||
|
0.0009492104739322405,
|
||||||
|
0.001536916169711772,
|
||||||
|
0.0020528749242516003,
|
||||||
|
0.0024661761828563313,
|
||||||
|
0.002751173465403013,
|
||||||
|
0.0028891772783515117,
|
||||||
|
0.0028695579254982137,
|
||||||
|
0.002690486553108668,
|
||||||
|
0.002359106318284556,
|
||||||
|
0.0018913307558827979,
|
||||||
|
0.0013113627449627718,
|
||||||
|
0.0006501370380893174,
|
||||||
|
-0.00005591634751310549,
|
||||||
|
-0.0007677972770164452,
|
||||||
|
-0.001444647221437417,
|
||||||
|
-0.00204746257956741,
|
||||||
|
-0.0025398901810068483,
|
||||||
|
-0.002891736526827703,
|
||||||
|
-0.0030803898442519225,
|
||||||
|
-0.003091468726777203,
|
||||||
|
-0.0029207038921516223,
|
||||||
|
-0.0025741254950366896,
|
||||||
|
-0.002067973931355495,
|
||||||
|
-0.0014280157557714668,
|
||||||
|
-0.0006877721381443566,
|
||||||
|
0.0001126863109365815,
|
||||||
|
0.0009284005715601569,
|
||||||
|
0.0017128970482479869,
|
||||||
|
0.0024209880361363485,
|
||||||
|
0.003010137740662827,
|
||||||
|
0.0034433436111773724,
|
||||||
|
0.0036925735900344213,
|
||||||
|
0.0037392776355320164,
|
||||||
|
0.0035750549963301497,
|
||||||
|
0.003204686888263029,
|
||||||
|
0.002644455073483638,
|
||||||
|
0.0019206891969597553,
|
||||||
|
0.0010720437886563461,
|
||||||
|
0.00014236365066494383,
|
||||||
|
-0.0008162193794978551,
|
||||||
|
-0.001750205816244383,
|
||||||
|
-0.00260524888853366,
|
||||||
|
-0.003330448634355011,
|
||||||
|
-0.0038806885762527085,
|
||||||
|
-0.0042197018719619,
|
||||||
|
-0.004322310610781536,
|
||||||
|
-0.004175978670258643,
|
||||||
|
-0.003781919171806373,
|
||||||
|
-0.0031554249088873213,
|
||||||
|
-0.0023255577897850145,
|
||||||
|
-0.0013338142329436104,
|
||||||
|
-0.0002321551782802385,
|
||||||
|
0.000919847567321573,
|
||||||
|
0.002057758110308816,
|
||||||
|
0.0031159521593161162,
|
||||||
|
0.004031228465119642,
|
||||||
|
0.004746373230231019,
|
||||||
|
0.005213833074755009,
|
||||||
|
0.005398368179397916,
|
||||||
|
0.005279622770016463,
|
||||||
|
0.0048537340045996654,
|
||||||
|
0.004133945043852994,
|
||||||
|
0.003150792733934946,
|
||||||
|
0.0019506897625897466,
|
||||||
|
0.0005941555193940558,
|
||||||
|
-0.0008472848222071792,
|
||||||
|
-0.002294579340030699,
|
||||||
|
-0.0036652622277313592,
|
||||||
|
-0.004877798689965437,
|
||||||
|
-0.00585630529385358,
|
||||||
|
-0.006535021981369312,
|
||||||
|
-0.006862209393606202,
|
||||||
|
-0.006803716425690461,
|
||||||
|
-0.0063451726267535384,
|
||||||
|
-0.005494638978117847,
|
||||||
|
-0.004281728798042104,
|
||||||
|
-0.0027587324158575986,
|
||||||
|
-0.0009964288997051905,
|
||||||
|
0.0009165389378955883,
|
||||||
|
0.002878840922760619,
|
||||||
|
0.00478156331351961,
|
||||||
|
0.0065128972068082235,
|
||||||
|
0.00796484714665623,
|
||||||
|
0.009038598083889997,
|
||||||
|
0.009650143724551814,
|
||||||
|
0.009736399158760185,
|
||||||
|
0.009259146172550439,
|
||||||
|
0.008207929636538491,
|
||||||
|
0.006603125277341979,
|
||||||
|
0.004496736872907695,
|
||||||
|
0.0019706087511477417,
|
||||||
|
-0.0008653143095612088,
|
||||||
|
-0.0038758915334291878,
|
||||||
|
-0.006906924032827862,
|
||||||
|
-0.00979143836062656,
|
||||||
|
-0.012355548332571993,
|
||||||
|
-0.014427563844913744,
|
||||||
|
-0.015845425534902112,
|
||||||
|
-0.016463427343763833,
|
||||||
|
-0.016162193538925198,
|
||||||
|
-0.014851592429837827,
|
||||||
|
-0.012479356514209913,
|
||||||
|
-0.009032813295982706,
|
||||||
|
-0.00454241087129261,
|
||||||
|
0.0009187305291106804,
|
||||||
|
0.007235761344299075,
|
||||||
|
0.014255324035897835,
|
||||||
|
0.021790491494704824,
|
||||||
|
0.029627294762135707,
|
||||||
|
0.03753261929369517,
|
||||||
|
0.04526278875865766,
|
||||||
|
0.05257290583779067,
|
||||||
|
0.05922632186497995,
|
||||||
|
0.06500420017090862,
|
||||||
|
0.06971390965779961,
|
||||||
|
0.07319701890747447,
|
||||||
|
0.07533548531500543,
|
||||||
|
0.07605647784784841,
|
||||||
|
0.07533548531500543,
|
||||||
|
0.07319701890747447,
|
||||||
|
0.06971390965779961,
|
||||||
|
0.06500420017090862,
|
||||||
|
0.05922632186497995,
|
||||||
|
0.05257290583779067,
|
||||||
|
0.04526278875865766,
|
||||||
|
0.03753261929369517,
|
||||||
|
0.029627294762135707,
|
||||||
|
0.021790491494704824,
|
||||||
|
0.014255324035897835,
|
||||||
|
0.007235761344299075,
|
||||||
|
0.0009187305291106804,
|
||||||
|
-0.00454241087129261,
|
||||||
|
-0.009032813295982706,
|
||||||
|
-0.012479356514209913,
|
||||||
|
-0.014851592429837827,
|
||||||
|
-0.016162193538925198,
|
||||||
|
-0.016463427343763833,
|
||||||
|
-0.015845425534902112,
|
||||||
|
-0.014427563844913744,
|
||||||
|
-0.012355548332571993,
|
||||||
|
-0.00979143836062656,
|
||||||
|
-0.006906924032827862,
|
||||||
|
-0.0038758915334291878,
|
||||||
|
-0.0008653143095612088,
|
||||||
|
0.0019706087511477417,
|
||||||
|
0.004496736872907695,
|
||||||
|
0.006603125277341979,
|
||||||
|
0.008207929636538491,
|
||||||
|
0.009259146172550439,
|
||||||
|
0.009736399158760185,
|
||||||
|
0.009650143724551814,
|
||||||
|
0.009038598083889997,
|
||||||
|
0.00796484714665623,
|
||||||
|
0.0065128972068082235,
|
||||||
|
0.00478156331351961,
|
||||||
|
0.002878840922760619,
|
||||||
|
0.0009165389378955883,
|
||||||
|
-0.0009964288997051905,
|
||||||
|
-0.0027587324158575986,
|
||||||
|
-0.004281728798042104,
|
||||||
|
-0.005494638978117847,
|
||||||
|
-0.0063451726267535384,
|
||||||
|
-0.006803716425690461,
|
||||||
|
-0.006862209393606202,
|
||||||
|
-0.006535021981369312,
|
||||||
|
-0.00585630529385358,
|
||||||
|
-0.004877798689965437,
|
||||||
|
-0.0036652622277313592,
|
||||||
|
-0.002294579340030699,
|
||||||
|
-0.0008472848222071792,
|
||||||
|
0.0005941555193940558,
|
||||||
|
0.0019506897625897466,
|
||||||
|
0.003150792733934946,
|
||||||
|
0.004133945043852994,
|
||||||
|
0.0048537340045996654,
|
||||||
|
0.005279622770016463,
|
||||||
|
0.005398368179397916,
|
||||||
|
0.005213833074755009,
|
||||||
|
0.004746373230231019,
|
||||||
|
0.004031228465119642,
|
||||||
|
0.0031159521593161162,
|
||||||
|
0.002057758110308816,
|
||||||
|
0.000919847567321573,
|
||||||
|
-0.0002321551782802385,
|
||||||
|
-0.0013338142329436104,
|
||||||
|
-0.0023255577897850145,
|
||||||
|
-0.0031554249088873213,
|
||||||
|
-0.003781919171806373,
|
||||||
|
-0.004175978670258643,
|
||||||
|
-0.004322310610781536,
|
||||||
|
-0.0042197018719619,
|
||||||
|
-0.0038806885762527085,
|
||||||
|
-0.003330448634355011,
|
||||||
|
-0.00260524888853366,
|
||||||
|
-0.001750205816244383,
|
||||||
|
-0.0008162193794978551,
|
||||||
|
0.00014236365066494383,
|
||||||
|
0.0010720437886563461,
|
||||||
|
0.0019206891969597553,
|
||||||
|
0.002644455073483638,
|
||||||
|
0.003204686888263029,
|
||||||
|
0.0035750549963301497,
|
||||||
|
0.0037392776355320164,
|
||||||
|
0.0036925735900344213,
|
||||||
|
0.0034433436111773724,
|
||||||
|
0.003010137740662827,
|
||||||
|
0.0024209880361363485,
|
||||||
|
0.0017128970482479869,
|
||||||
|
0.0009284005715601569,
|
||||||
|
0.0001126863109365815,
|
||||||
|
-0.0006877721381443566,
|
||||||
|
-0.0014280157557714668,
|
||||||
|
-0.002067973931355495,
|
||||||
|
-0.0025741254950366896,
|
||||||
|
-0.0029207038921516223,
|
||||||
|
-0.003091468726777203,
|
||||||
|
-0.0030803898442519225,
|
||||||
|
-0.002891736526827703,
|
||||||
|
-0.0025398901810068483,
|
||||||
|
-0.00204746257956741,
|
||||||
|
-0.001444647221437417,
|
||||||
|
-0.0007677972770164452,
|
||||||
|
-0.00005591634751310549,
|
||||||
|
0.0006501370380893174,
|
||||||
|
0.0013113627449627718,
|
||||||
|
0.0018913307558827979,
|
||||||
|
0.002359106318284556,
|
||||||
|
0.002690486553108668,
|
||||||
|
0.0028695579254982137,
|
||||||
|
0.0028891772783515117,
|
||||||
|
0.002751173465403013,
|
||||||
|
0.0024661761828563313,
|
||||||
|
0.0020528749242516003,
|
||||||
|
0.001536916169711772,
|
||||||
|
0.0009492104739322405,
|
||||||
|
0.00032421742432794986,
|
||||||
|
-0.0003023080541089114,
|
||||||
|
-0.000894944574293136,
|
||||||
|
-0.0014208790055546586,
|
||||||
|
-0.00185139126645343,
|
||||||
|
-0.0021636093678711237,
|
||||||
|
-0.002341854284500264,
|
||||||
|
-0.002378134377120082,
|
||||||
|
-0.0022726649592763708,
|
||||||
|
-0.002033429226170653,
|
||||||
|
-0.0016757415624847984,
|
||||||
|
-0.0012215159916327684,
|
||||||
|
-0.0006976628796186629,
|
||||||
|
-0.0001346731858706825,
|
||||||
|
0.00043530470972525385,
|
||||||
|
0.0009802099743280804,
|
||||||
|
0.0014698815939004595,
|
||||||
|
0.0018776951564996795,
|
||||||
|
0.002182089414459102,
|
||||||
|
0.0023675334058277852,
|
||||||
|
0.0024253663999272922,
|
||||||
|
0.002354435255283183,
|
||||||
|
0.0021606030300284607,
|
||||||
|
0.001857288190223437,
|
||||||
|
0.001462016316333705,
|
||||||
|
0.0010006023914098225,
|
||||||
|
0.0004975083602194651,
|
||||||
|
-0.00001565838520828236,
|
||||||
|
-0.0005108126444730755,
|
||||||
|
-0.0009605147153735846,
|
||||||
|
-0.001338448595903364,
|
||||||
|
-0.0016246736311703472,
|
||||||
|
-0.0018046936739308204,
|
||||||
|
-0.0018687427312488538,
|
||||||
|
-0.0018142393477275655,
|
||||||
|
-0.0016462249002119438,
|
||||||
|
-0.0013754156241168216,
|
||||||
|
-0.0010176577556310668,
|
||||||
|
-0.0005940260022155878,
|
||||||
|
-0.00012940307877066482,
|
||||||
|
0.00034959201045762735,
|
||||||
|
0.0008161029752255834,
|
||||||
|
0.001244407904014974,
|
||||||
|
0.0016108477670202955,
|
||||||
|
0.0018952302758044716,
|
||||||
|
0.0020828998261889996,
|
||||||
|
0.0021647196370404324,
|
||||||
|
0.0021373573333903907,
|
||||||
|
0.0020038657435381257,
|
||||||
|
0.0017727389893637477,
|
||||||
|
0.0014587022318349155,
|
||||||
|
0.0010805902221096093,
|
||||||
|
0.0006609144606176251,
|
||||||
|
0.00022392080409527296,
|
||||||
|
-0.0002053053709292688,
|
||||||
|
-0.0006023329394979184,
|
||||||
|
-0.000944644997827479,
|
||||||
|
-0.001212981144562626,
|
||||||
|
-0.0013925554944245599,
|
||||||
|
-0.0014738073952633322,
|
||||||
|
-0.001452868444758477,
|
||||||
|
-0.001331475322813246,
|
||||||
|
-0.0011170665364279842,
|
||||||
|
-0.0008220930819068703,
|
||||||
|
-0.0004637552851828441,
|
||||||
|
-0.00006253548108123283,
|
||||||
|
0.00035878897793891384,
|
||||||
|
0.0007765672753843151,
|
||||||
|
0.0011676956517593336,
|
||||||
|
0.0015105823732014887,
|
||||||
|
0.001786670875323066,
|
||||||
|
0.0019812511669580956,
|
||||||
|
0.002084241239549793,
|
||||||
|
0.0020909788043975276,
|
||||||
|
0.0020022457010850096,
|
||||||
|
0.001824332418711941,
|
||||||
|
0.0015684774729692547,
|
||||||
|
0.001250150108424033,
|
||||||
|
0.0008882139336450031,
|
||||||
|
0.0005039966417534989,
|
||||||
|
0.00011989306001557591,
|
||||||
|
-0.00024184631248718984,
|
||||||
|
-0.0005602703726361708,
|
||||||
|
-0.0008171434769424912,
|
||||||
|
-0.0009972609130431105,
|
||||||
|
-0.0010918347055704724,
|
||||||
|
-0.0010922057096824714,
|
||||||
|
-0.0010037105425627479,
|
||||||
|
-0.0008248106197065263,
|
||||||
|
-0.0005702276065943115,
|
||||||
|
-0.0002535400937416474,
|
||||||
|
0.00011015896725885363,
|
||||||
|
0.0004988789779988034,
|
||||||
|
0.0008900089027853051,
|
||||||
|
0.0012633901100129934,
|
||||||
|
0.0015991122050812935,
|
||||||
|
0.0018778523547873093,
|
||||||
|
0.002084143087394179,
|
||||||
|
0.0022077928016267247,
|
||||||
|
0.002243244512808436,
|
||||||
|
0.0021891204599193454,
|
||||||
|
0.0020487233738411786,
|
||||||
|
0.0018306821451188385,
|
||||||
|
0.001548740624466772,
|
||||||
|
0.0012200029156715312,
|
||||||
|
0.0008636162701018116,
|
||||||
|
0.0005003479818101034,
|
||||||
|
0.00015129060306465846,
|
||||||
|
-0.0001628354231637733,
|
||||||
|
-0.0004230530550807403,
|
||||||
|
-0.0006139467826508875,
|
||||||
|
-0.0007237724027604178,
|
||||||
|
-0.0007458291450652108,
|
||||||
|
-0.0006778152785331262,
|
||||||
|
-0.0005225020827002275,
|
||||||
|
-0.0002873259421258282,
|
||||||
|
0.00001556164895794005,
|
||||||
|
0.00037004878160910566,
|
||||||
|
0.0007570502661148399,
|
||||||
|
0.0011557133218574656,
|
||||||
|
0.0015446566595713781,
|
||||||
|
0.0019030267726684862,
|
||||||
|
0.0022116895646837804,
|
||||||
|
0.002454031118912115,
|
||||||
|
0.0026171805325111786,
|
||||||
|
0.0026923543124503487,
|
||||||
|
0.002675931198702369,
|
||||||
|
0.0025693090410960793,
|
||||||
|
0.0023791019266531147,
|
||||||
|
0.0021166520909361806,
|
||||||
|
0.0017971738401020903,
|
||||||
|
0.0014393167512730105,
|
||||||
|
0.0010638765819667507,
|
||||||
|
0.0006927997977343629,
|
||||||
|
0.0003481061116814,
|
||||||
|
0.00005048775593523694,
|
||||||
|
-0.00018159497394687693,
|
||||||
|
-0.000333110808989004,
|
||||||
|
-0.00039339019608776595,
|
||||||
|
-0.0003566665079835044,
|
||||||
|
-0.00022232703032059695,
|
||||||
|
0.000004837984574109052,
|
||||||
|
0.00031496346957593816,
|
||||||
|
0.0006936436970225945,
|
||||||
|
0.001122598250955268,
|
||||||
|
0.0015808468393586463,
|
||||||
|
0.002043603816320018,
|
||||||
|
0.0024934237802220847,
|
||||||
|
0.0028914904576434483,
|
||||||
|
0.00324212650920447,
|
||||||
|
0.003502213813807159,
|
||||||
|
0.003666696471321502,
|
||||||
|
0.00373312207850841,
|
||||||
|
0.0036920509207547503,
|
||||||
|
0.0035414284335566213,
|
||||||
|
0.003291074349553435,
|
||||||
|
0.0029568799307201055,
|
||||||
|
0.0025562644079397566,
|
||||||
|
0.0021085978153374337,
|
||||||
|
0.001636917920572586,
|
||||||
|
0.001167933929422274,
|
||||||
|
0.0007296960675978035,
|
||||||
|
0.00034866017633577485,
|
||||||
|
0.00004791480114281375,
|
||||||
|
-0.00015331390959515178,
|
||||||
|
-0.00024019085124103728,
|
||||||
|
-0.0002024986474888905,
|
||||||
|
-0.00003519485538394603,
|
||||||
|
0.00026038278850552165,
|
||||||
|
0.000676466760403685,
|
||||||
|
0.001198808101593799,
|
||||||
|
0.001807325109970609,
|
||||||
|
0.002477679601003533,
|
||||||
|
0.003181825807588361,
|
||||||
|
0.0038898729887556515,
|
||||||
|
0.004570706217926675,
|
||||||
|
0.0051935953163101374,
|
||||||
|
0.005729115424630075,
|
||||||
|
0.006150572165634373,
|
||||||
|
0.006435200226996191,
|
||||||
|
0.006565317350605899,
|
||||||
|
0.00652916985473517,
|
||||||
|
0.006321383314346843,
|
||||||
|
0.005943231522926785,
|
||||||
|
0.005402338389433701,
|
||||||
|
0.0047125166256176704,
|
||||||
|
0.003892678282644405,
|
||||||
|
0.0029665219630286475,
|
||||||
|
0.0019610873421838713,
|
||||||
|
0.0009061942378719186,
|
||||||
|
-0.00016698144545659763,
|
||||||
|
-0.0012271560122908633,
|
||||||
|
-0.0022438395226593234,
|
||||||
|
-0.003188871268023831,
|
||||||
|
-0.00403722847791321,
|
||||||
|
-0.00476798650929006,
|
||||||
|
-0.005365157561460779,
|
||||||
|
-0.005817832832522139,
|
||||||
|
-0.0061205500978807606,
|
||||||
|
-0.006273284055978816,
|
||||||
|
-0.0062810419368997195,
|
||||||
|
-0.006153352756740714,
|
||||||
|
-0.005903803434753803,
|
||||||
|
-0.005549178890478986,
|
||||||
|
-0.00510864933708306,
|
||||||
|
-0.004602917018038953,
|
||||||
|
-0.004053348584904465,
|
||||||
|
-0.0034810491402275856,
|
||||||
|
-0.002906124689895695,
|
||||||
|
-0.006276773743368246
|
||||||
|
};
|
||||||
|
|
||||||
|
void FM_Baseband_Filter_init(FM_Baseband_Filter* f) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < FM_BASEBAND_FILTER_TAP_NUM; ++i)
|
||||||
|
f->history[i] = 0;
|
||||||
|
f->last_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FM_Baseband_Filter_put(FM_Baseband_Filter* f, double input) {
|
||||||
|
f->history[f->last_index++] = input;
|
||||||
|
if(f->last_index == FM_BASEBAND_FILTER_TAP_NUM)
|
||||||
|
f->last_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double FM_Baseband_Filter_get(FM_Baseband_Filter* f) {
|
||||||
|
double acc = 0;
|
||||||
|
int index = f->last_index, i;
|
||||||
|
for(i = 0; i < FM_BASEBAND_FILTER_TAP_NUM; ++i) {
|
||||||
|
index = index != 0 ? index-1 : FM_BASEBAND_FILTER_TAP_NUM-1;
|
||||||
|
acc += f->history[index] * filter_taps[i];
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
35
src/broadcast_fm/fir_filters/FM_Baseband_Filter.h
Normal file
35
src/broadcast_fm/fir_filters/FM_Baseband_Filter.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef FM_BASEBAND_FILTER_H_
|
||||||
|
#define FM_BASEBAND_FILTER_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
FIR filter designed with
|
||||||
|
http://t-filter.appspot.com
|
||||||
|
|
||||||
|
sampling frequency: 2000000 Hz
|
||||||
|
|
||||||
|
* 0 Hz - 75000 Hz
|
||||||
|
gain = 1
|
||||||
|
desired ripple = 5 dB
|
||||||
|
actual ripple = 4.140342542562957 dB
|
||||||
|
|
||||||
|
* 78000 Hz - 1000000 Hz
|
||||||
|
gain = 0
|
||||||
|
desired attenuation = -40 dB
|
||||||
|
actual attenuation = -40.07162834583716 dB
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FM_BASEBAND_FILTER_TAP_NUM 655
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double history[FM_BASEBAND_FILTER_TAP_NUM];
|
||||||
|
unsigned int last_index;
|
||||||
|
} FM_Baseband_Filter;
|
||||||
|
|
||||||
|
void FM_Baseband_Filter_init(FM_Baseband_Filter* f);
|
||||||
|
void FM_Baseband_Filter_put(FM_Baseband_Filter* f, double input);
|
||||||
|
double FM_Baseband_Filter_get(FM_Baseband_Filter* f);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
2037
src/common/hxcmod/hxcmod.c
Normal file
2037
src/common/hxcmod/hxcmod.c
Normal file
File diff suppressed because it is too large
Load Diff
309
src/common/hxcmod/hxcmod.h
Normal file
309
src/common/hxcmod/hxcmod.h
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : hxcmod.h
|
||||||
|
// Contains: a tiny mod player
|
||||||
|
//
|
||||||
|
// Written by: Jean François DEL NERO
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef MODPLAY_DEF
|
||||||
|
#define MODPLAY_DEF
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HXCMOD_SLOW_TARGET
|
||||||
|
#define HXCMOD_STATE_REPORT_SUPPORT 1
|
||||||
|
#define HXCMOD_OUTPUT_FILTER 1
|
||||||
|
#define HXCMOD_OUTPUT_STEREO_MIX 1
|
||||||
|
#define HXCMOD_CLIPPING_CHECK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Warning : The following option
|
||||||
|
// required 32KB of additional RAM :
|
||||||
|
// #define HXCMOD_USE_PRECALC_VOLUME_TABLE 1
|
||||||
|
|
||||||
|
// Basic type
|
||||||
|
typedef unsigned char muchar;
|
||||||
|
typedef signed char mchar;
|
||||||
|
typedef unsigned short muint;
|
||||||
|
typedef short mint;
|
||||||
|
typedef unsigned long mulong;
|
||||||
|
|
||||||
|
#ifdef HXCMOD_16BITS_TARGET
|
||||||
|
typedef unsigned short mssize;
|
||||||
|
#else
|
||||||
|
typedef unsigned long mssize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HXCMOD_8BITS_OUTPUT
|
||||||
|
#ifdef HXCMOD_UNSIGNED_OUTPUT
|
||||||
|
typedef unsigned char msample;
|
||||||
|
#else
|
||||||
|
typedef signed char msample;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HXCMOD_UNSIGNED_OUTPUT
|
||||||
|
typedef unsigned short msample;
|
||||||
|
#else
|
||||||
|
typedef signed short msample;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HXCMOD_MAXCHANNELS
|
||||||
|
#define NUMMAXCHANNELS HXCMOD_MAXCHANNELS
|
||||||
|
#else
|
||||||
|
#define NUMMAXCHANNELS 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAXNOTES 12*12
|
||||||
|
|
||||||
|
//
|
||||||
|
// MOD file structures
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
muchar name[22];
|
||||||
|
muint length;
|
||||||
|
muchar finetune;
|
||||||
|
muchar volume;
|
||||||
|
muint reppnt;
|
||||||
|
muint replen;
|
||||||
|
} sample;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
muchar sampperiod;
|
||||||
|
muchar period;
|
||||||
|
muchar sampeffect;
|
||||||
|
muchar effect;
|
||||||
|
} note;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
muchar title[20];
|
||||||
|
sample samples[31];
|
||||||
|
muchar length;
|
||||||
|
muchar protracker;
|
||||||
|
muchar patterntable[128];
|
||||||
|
muchar signature[4];
|
||||||
|
muchar speed;
|
||||||
|
} module;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
//
|
||||||
|
// HxCMod Internal structures
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
mchar * sampdata;
|
||||||
|
muint length;
|
||||||
|
muint reppnt;
|
||||||
|
muint replen;
|
||||||
|
muchar sampnum;
|
||||||
|
|
||||||
|
mchar * nxt_sampdata;
|
||||||
|
muint nxt_length;
|
||||||
|
muint nxt_reppnt;
|
||||||
|
muint nxt_replen;
|
||||||
|
muchar update_nxt_repeat;
|
||||||
|
|
||||||
|
mchar * dly_sampdata;
|
||||||
|
muint dly_length;
|
||||||
|
muint dly_reppnt;
|
||||||
|
muint dly_replen;
|
||||||
|
muchar note_delay;
|
||||||
|
|
||||||
|
mchar * lst_sampdata;
|
||||||
|
muint lst_length;
|
||||||
|
muint lst_reppnt;
|
||||||
|
muint lst_replen;
|
||||||
|
muchar retrig_cnt;
|
||||||
|
muchar retrig_param;
|
||||||
|
|
||||||
|
muint funkoffset;
|
||||||
|
mint funkspeed;
|
||||||
|
|
||||||
|
mint glissando;
|
||||||
|
|
||||||
|
mulong samppos;
|
||||||
|
mulong sampinc;
|
||||||
|
muint period;
|
||||||
|
muchar volume;
|
||||||
|
#ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
|
||||||
|
mint * volume_table;
|
||||||
|
#endif
|
||||||
|
muchar effect;
|
||||||
|
muchar parameffect;
|
||||||
|
muint effect_code;
|
||||||
|
|
||||||
|
mulong last_set_offset;
|
||||||
|
|
||||||
|
mint decalperiod;
|
||||||
|
mint portaspeed;
|
||||||
|
mint portaperiod;
|
||||||
|
mint vibraperiod;
|
||||||
|
mint Arpperiods[3];
|
||||||
|
muchar ArpIndex;
|
||||||
|
|
||||||
|
muchar volumeslide;
|
||||||
|
|
||||||
|
muchar vibraparam;
|
||||||
|
muchar vibrapointeur;
|
||||||
|
|
||||||
|
muchar finetune;
|
||||||
|
|
||||||
|
muchar cut_param;
|
||||||
|
|
||||||
|
muint patternloopcnt;
|
||||||
|
muint patternloopstartpoint;
|
||||||
|
} channel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
module song;
|
||||||
|
mchar * sampledata[31];
|
||||||
|
note * patterndata[128];
|
||||||
|
|
||||||
|
#ifdef HXCMOD_16BITS_TARGET
|
||||||
|
muint playrate;
|
||||||
|
#else
|
||||||
|
mulong playrate;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
muint tablepos;
|
||||||
|
muint patternpos;
|
||||||
|
muint patterndelay;
|
||||||
|
muchar jump_loop_effect;
|
||||||
|
muchar bpm;
|
||||||
|
|
||||||
|
#ifdef HXCMOD_16BITS_TARGET
|
||||||
|
muint patternticks;
|
||||||
|
muint patterntickse;
|
||||||
|
muint patternticksaim;
|
||||||
|
muint patternticksem;
|
||||||
|
muint tick_cnt;
|
||||||
|
#else
|
||||||
|
mulong patternticks;
|
||||||
|
mulong patterntickse;
|
||||||
|
mulong patternticksaim;
|
||||||
|
mulong patternticksem;
|
||||||
|
mulong tick_cnt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mulong sampleticksconst;
|
||||||
|
|
||||||
|
channel channels[NUMMAXCHANNELS];
|
||||||
|
|
||||||
|
muint number_of_channels;
|
||||||
|
|
||||||
|
muint mod_loaded;
|
||||||
|
|
||||||
|
mint last_r_sample;
|
||||||
|
mint last_l_sample;
|
||||||
|
|
||||||
|
mint stereo;
|
||||||
|
mint stereo_separation;
|
||||||
|
mint bits;
|
||||||
|
mint filter;
|
||||||
|
|
||||||
|
#ifdef EFFECTS_USAGE_STATE
|
||||||
|
int effects_event_counts[32];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
|
||||||
|
mint precalc_volume_array[65*256];
|
||||||
|
mint * volume_selection_table[65];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} modcontext;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Player states structures
|
||||||
|
//
|
||||||
|
typedef struct track_state_
|
||||||
|
{
|
||||||
|
unsigned char instrument_number;
|
||||||
|
unsigned short cur_period;
|
||||||
|
unsigned char cur_volume;
|
||||||
|
unsigned short cur_effect;
|
||||||
|
unsigned short cur_parameffect;
|
||||||
|
}track_state;
|
||||||
|
|
||||||
|
typedef struct tracker_state_
|
||||||
|
{
|
||||||
|
int number_of_tracks;
|
||||||
|
int bpm;
|
||||||
|
int speed;
|
||||||
|
int cur_pattern;
|
||||||
|
int cur_pattern_pos;
|
||||||
|
int cur_pattern_table_pos;
|
||||||
|
unsigned int buf_index;
|
||||||
|
track_state tracks[NUMMAXCHANNELS];
|
||||||
|
}tracker_state;
|
||||||
|
|
||||||
|
typedef struct tracker_state_instrument_
|
||||||
|
{
|
||||||
|
char name[22];
|
||||||
|
int active;
|
||||||
|
}tracker_state_instrument;
|
||||||
|
|
||||||
|
typedef struct tracker_buffer_state_
|
||||||
|
{
|
||||||
|
int nb_max_of_state;
|
||||||
|
int nb_of_state;
|
||||||
|
int cur_rd_index;
|
||||||
|
int sample_step;
|
||||||
|
char name[64];
|
||||||
|
tracker_state_instrument instruments[31];
|
||||||
|
tracker_state * track_state_buf;
|
||||||
|
}tracker_buffer_state;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// HxCMOD Core API:
|
||||||
|
// -------------------------------------------
|
||||||
|
// int hxcmod_init(modcontext * modctx)
|
||||||
|
//
|
||||||
|
// - Initialize the modcontext buffer. Must be called before doing anything else.
|
||||||
|
// Return 1 if success. 0 in case of error.
|
||||||
|
// -------------------------------------------
|
||||||
|
// int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size )
|
||||||
|
//
|
||||||
|
// - "Load" a MOD from memory (from "mod_data" with size "mod_data_size").
|
||||||
|
// Return 1 if success. 0 in case of error.
|
||||||
|
// -------------------------------------------
|
||||||
|
// void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, mssize nbsample, tracker_buffer_state * trkbuf )
|
||||||
|
//
|
||||||
|
// - Generate and return the next samples chunk to outbuffer.
|
||||||
|
// nbsample specify the number of stereo 16bits samples you want.
|
||||||
|
// The output format is signed 44100Hz 16-bit Stereo PCM samples.
|
||||||
|
// The output buffer size in byte must be equal to ( nbsample * 2 * 2 ).
|
||||||
|
// The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused.
|
||||||
|
// -------------------------------------------
|
||||||
|
// void hxcmod_unload( modcontext * modctx )
|
||||||
|
//
|
||||||
|
// - "Unload" / clear the player status.
|
||||||
|
// -------------------------------------------
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int hxcmod_init( modcontext * modctx );
|
||||||
|
int hxcmod_setcfg( modcontext * modctx, int samplerate, int stereo_separation, int filter );
|
||||||
|
int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size );
|
||||||
|
void hxcmod_fillbuffer( modcontext * modctx, msample * outbuffer, mssize nbsample, tracker_buffer_state * trkbuf );
|
||||||
|
void hxcmod_unload( modcontext * modctx );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MODPLAY_DEF */
|
86
src/common/modulator.c
Normal file
86
src/common/modulator.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : modulator.c
|
||||||
|
// Contains: oscillator and IQ modulator
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "modulator.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Note about the IQ
|
||||||
|
//
|
||||||
|
// If NCO enabled and If I="cos", Q="sin" -> Output Freq = NCO Freq + IQ Freq
|
||||||
|
// If NCO enabled and If I="sin", Q="cos" -> Output Freq = NCO Freq - IQ Freq
|
||||||
|
// If NCO enabled and If I="cos", Q="cos" -> Output Freq = NCO Freq - IQ Freq AND NCO Freq + IQ Freq
|
||||||
|
// If NCO enabled and If I="const", Q="sin" -> Output Freq = NCO Freq - IQ Freq AND NCO Freq AND NCO Freq + IQ Freq
|
||||||
|
// If NCO enabled and If I="const", Q="const" -> Output Freq = NCO Freq
|
||||||
|
//
|
||||||
|
|
||||||
|
uint16_t get_next_iq(iq_wave_gen * wg)
|
||||||
|
{
|
||||||
|
int i_sample,q_sample;
|
||||||
|
|
||||||
|
char i_ub_sample,q_ub_sample;
|
||||||
|
|
||||||
|
i_sample = (int)(cos(wg->phase)*wg->Amplitude);
|
||||||
|
q_sample = (int)(sin(wg->phase)*wg->Amplitude);
|
||||||
|
|
||||||
|
wg->phase += ( (2.0 * PI * wg->Frequency) / (double)wg->sample_rate );
|
||||||
|
|
||||||
|
/* if(wg->phase > (2.0 * PI) )
|
||||||
|
wg->phase -= (2.0 * PI);
|
||||||
|
|
||||||
|
if(wg->phase < (-2.0 * PI) )
|
||||||
|
wg->phase += (2.0 * PI);
|
||||||
|
*/
|
||||||
|
|
||||||
|
i_ub_sample = (i_sample);
|
||||||
|
q_ub_sample = (q_sample);
|
||||||
|
|
||||||
|
return (unsigned short)((i_ub_sample)&0xFF) | ((((unsigned short)q_ub_sample)<<8)&0xFF00);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2*PI -> One cycle.
|
||||||
|
// Phase step = ( (2 * PI) / (SAMPLE_RATE / Frequency) ) -> ( (2 * PI) * Frequency ) / SAMPLE_RATE
|
||||||
|
//
|
||||||
|
|
||||||
|
double f_get_next_sample(wave_gen * wg)
|
||||||
|
{
|
||||||
|
double sample;
|
||||||
|
|
||||||
|
sample = ( cos( wg->phase ) * wg->Amplitude );
|
||||||
|
|
||||||
|
wg->phase += ( (2.0 * PI * wg->Frequency) / (double)wg->sample_rate );
|
||||||
|
|
||||||
|
if(wg->phase > (2.0 * PI) )
|
||||||
|
wg->phase -= (2.0 * PI);
|
||||||
|
|
||||||
|
if(wg->phase < (-2.0 * PI) )
|
||||||
|
wg->phase += (2.0 * PI);
|
||||||
|
|
||||||
|
return sample;
|
||||||
|
}
|
65
src/common/modulator.h
Normal file
65
src/common/modulator.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : modulator.h
|
||||||
|
// Contains: oscillator and IQ modulator
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __MODULATOR_H__
|
||||||
|
#define __MODULATOR_H__
|
||||||
|
|
||||||
|
#if defined(M_PI)
|
||||||
|
#define PI M_PI
|
||||||
|
#else
|
||||||
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct iq_wave_gen_
|
||||||
|
{
|
||||||
|
double phase;
|
||||||
|
|
||||||
|
double Frequency,OldFrequency;
|
||||||
|
|
||||||
|
int sample_rate;
|
||||||
|
double Amplitude;
|
||||||
|
}iq_wave_gen;
|
||||||
|
|
||||||
|
typedef struct wave_gen_
|
||||||
|
{
|
||||||
|
double phase;
|
||||||
|
|
||||||
|
double Frequency,OldFrequency;
|
||||||
|
|
||||||
|
int sample_rate;
|
||||||
|
double Amplitude;
|
||||||
|
}wave_gen;
|
||||||
|
|
||||||
|
int find_zero_phase_index(short * buf, int size);
|
||||||
|
double find_phase(iq_wave_gen * wg, double sinoffset,short samplevalue,short * buf, int size);
|
||||||
|
int Fill_IQ_Wave_Buffer(iq_wave_gen * wg,unsigned short * wave_buf, int Size);
|
||||||
|
uint16_t get_next_iq(iq_wave_gen * wg);
|
||||||
|
|
||||||
|
int get_next_sample(wave_gen * wg);
|
||||||
|
|
||||||
|
double f_get_next_sample(wave_gen * wg);
|
||||||
|
|
||||||
|
#endif
|
97
src/common/rand_gen.c
Normal file
97
src/common/rand_gen.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : rand_gen.c
|
||||||
|
// Contains: random generators
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "rand_gen.h"
|
||||||
|
|
||||||
|
uint8_t rand_gen_get_next_byte(rand_gen_state *state)
|
||||||
|
{
|
||||||
|
uint8_t retbyte;
|
||||||
|
uint32_t seed;
|
||||||
|
uint32_t byte_number;
|
||||||
|
|
||||||
|
seed = state->current_seed;
|
||||||
|
byte_number = state->byte_number;
|
||||||
|
|
||||||
|
if( byte_number > 3 )
|
||||||
|
{
|
||||||
|
byte_number = 0x00;
|
||||||
|
|
||||||
|
/* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
|
||||||
|
seed ^= seed << 13;
|
||||||
|
seed ^= seed >> 17;
|
||||||
|
seed ^= seed << 5;
|
||||||
|
|
||||||
|
state->current_seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
retbyte = ( seed >> ( (3 - byte_number) << 3) ) & 0xFF;
|
||||||
|
|
||||||
|
byte_number++;
|
||||||
|
|
||||||
|
state->byte_number = byte_number;
|
||||||
|
|
||||||
|
return retbyte;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rand_gen_get_next_word(rand_gen_state *state)
|
||||||
|
{
|
||||||
|
uint32_t retword;
|
||||||
|
uint32_t seed;
|
||||||
|
|
||||||
|
seed = state->current_seed;
|
||||||
|
|
||||||
|
retword = seed;
|
||||||
|
|
||||||
|
/* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
|
||||||
|
seed ^= seed << 13;
|
||||||
|
seed ^= seed >> 17;
|
||||||
|
seed ^= seed << 5;
|
||||||
|
|
||||||
|
state->byte_number = 0x00;
|
||||||
|
state->current_seed = seed;
|
||||||
|
|
||||||
|
return retword;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rand_gen_init(rand_gen_state *state, uint32_t seed )
|
||||||
|
{
|
||||||
|
if(!state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( seed )
|
||||||
|
{
|
||||||
|
state->current_seed = seed;
|
||||||
|
state->byte_number = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->current_seed = 0x12E6C816;
|
||||||
|
state->byte_number = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
41
src/common/rand_gen.h
Normal file
41
src/common/rand_gen.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : rand_gen.h
|
||||||
|
// Contains: random generators
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __RAND_GEN_H__
|
||||||
|
#define __RAND_GEN_H__
|
||||||
|
|
||||||
|
typedef struct _rand_gen_state
|
||||||
|
{
|
||||||
|
uint32_t current_seed;
|
||||||
|
int byte_number;
|
||||||
|
} rand_gen_state;
|
||||||
|
|
||||||
|
void rand_gen_init(rand_gen_state *state, uint32_t seed );
|
||||||
|
uint8_t rand_gen_get_next_byte(rand_gen_state *state);
|
||||||
|
uint32_t rand_gen_get_next_word(rand_gen_state *state);
|
||||||
|
|
||||||
|
#endif /* __RAND_GEN_H__ */
|
||||||
|
|
126
src/common/utils.c
Normal file
126
src/common/utils.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : utils.h
|
||||||
|
// Contains: misc / utils functions
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void get_filename(char * path,char * filename)
|
||||||
|
{
|
||||||
|
int i,done;
|
||||||
|
|
||||||
|
i=strlen(path);
|
||||||
|
done=0;
|
||||||
|
while(i && !done)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
|
||||||
|
if(path[i]=='/')
|
||||||
|
{
|
||||||
|
done=1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(filename,"%s",&path[i]);
|
||||||
|
|
||||||
|
i=0;
|
||||||
|
while(filename[i])
|
||||||
|
{
|
||||||
|
if(filename[i]=='.')
|
||||||
|
{
|
||||||
|
filename[i]='_';
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_printable_char(unsigned char c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char specialchar[]={"&#{}()|_@=$!?;+*-"};
|
||||||
|
|
||||||
|
if( (c >= 'A' && c <= 'Z') ||
|
||||||
|
(c >= 'a' && c <= 'z') ||
|
||||||
|
(c >= '0' && c <= '9') )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while(specialchar[i])
|
||||||
|
{
|
||||||
|
if(specialchar[i] == c)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printbuf(void * buf,int size)
|
||||||
|
{
|
||||||
|
#define PRINTBUF_HEXPERLINE 16
|
||||||
|
#define PRINTBUF_MAXLINE_SIZE ((3*PRINTBUF_HEXPERLINE)+1+PRINTBUF_HEXPERLINE+2)
|
||||||
|
|
||||||
|
int i,j;
|
||||||
|
unsigned char *ptr = buf;
|
||||||
|
char tmp[8];
|
||||||
|
char str[PRINTBUF_MAXLINE_SIZE];
|
||||||
|
|
||||||
|
memset(str, ' ', PRINTBUF_MAXLINE_SIZE);
|
||||||
|
str[PRINTBUF_MAXLINE_SIZE-1] = 0;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for(i=0;i<size;i++)
|
||||||
|
{
|
||||||
|
if(!(i&(PRINTBUF_HEXPERLINE-1)) && i)
|
||||||
|
{
|
||||||
|
printf("%s\n", str);
|
||||||
|
memset(str, ' ', PRINTBUF_MAXLINE_SIZE);
|
||||||
|
str[PRINTBUF_MAXLINE_SIZE-1] = 0;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(tmp, "%02X", ptr[i]);
|
||||||
|
memcpy(&str[j*3],tmp,2);
|
||||||
|
|
||||||
|
if( is_printable_char(ptr[i]) )
|
||||||
|
str[3*PRINTBUF_HEXPERLINE + 1 + j] = ptr[i];
|
||||||
|
else
|
||||||
|
str[3*PRINTBUF_HEXPERLINE + 1 + j] = '.';
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", str);
|
||||||
|
}
|
30
src/common/utils.h
Normal file
30
src/common/utils.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : utils.h
|
||||||
|
// Contains: misc / utils functions
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void get_filename(char * path,char * filename);
|
||||||
|
void printbuf(unsigned char * buf,int size);
|
||||||
|
int is_printable_char(unsigned char c);
|
||||||
|
|
160
src/common/wave.c
Normal file
160
src/common/wave.c
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : wave.c
|
||||||
|
// Contains: wave file helpers
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "wave.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
wave_io * create_wave(char * path,int samplerate, int type)
|
||||||
|
{
|
||||||
|
wav_hdr wavhdr;
|
||||||
|
wave_io * w_io;
|
||||||
|
int sample_byte_size;
|
||||||
|
|
||||||
|
w_io = malloc(sizeof(wave_io));
|
||||||
|
if(w_io)
|
||||||
|
{
|
||||||
|
memset(w_io,0,sizeof(wave_io));
|
||||||
|
|
||||||
|
if(!path)
|
||||||
|
w_io->file = stdout;//fopen(stdout,"w+b");
|
||||||
|
else
|
||||||
|
w_io->file = fopen(path,"w+b");
|
||||||
|
|
||||||
|
if(w_io->file)
|
||||||
|
{
|
||||||
|
w_io->total_nb_samples = 0;
|
||||||
|
w_io->type = type;
|
||||||
|
switch(w_io->type)
|
||||||
|
{
|
||||||
|
case WAVE_FILE_FORMAT_RAW_8BITS_IQ: // Raw / IQ
|
||||||
|
w_io->sample_byte_size = 2; // I + Q
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAVE_FILE_FORMAT_WAV_8BITS_STEREO: // Wave 8 bits stereo
|
||||||
|
case WAVE_FILE_FORMAT_WAV_16BITS_STEREO: // Wave 16 bits stereo
|
||||||
|
case WAVE_FILE_FORMAT_WAV_16BITS_MONO: // Wave 16 bits mono
|
||||||
|
memset(&wavhdr,0,sizeof(wavhdr));
|
||||||
|
|
||||||
|
memcpy((char*)&wavhdr.RIFF,"RIFF",4);
|
||||||
|
memcpy((char*)&wavhdr.WAVE,"WAVE",4);
|
||||||
|
memcpy((char*)&wavhdr.fmt,"fmt ",4);
|
||||||
|
wavhdr.Subchunk1Size = 16;
|
||||||
|
wavhdr.AudioFormat = 1;
|
||||||
|
|
||||||
|
wavhdr.NumOfChan = 2; // I & Q
|
||||||
|
if(w_io->type == WAVE_FILE_FORMAT_WAV_16BITS_MONO)
|
||||||
|
wavhdr.NumOfChan = 1;
|
||||||
|
|
||||||
|
wavhdr.SamplesPerSec = samplerate;
|
||||||
|
if(w_io->type == WAVE_FILE_FORMAT_WAV_8BITS_STEREO)
|
||||||
|
wavhdr.bitsPerSample = 8;
|
||||||
|
else
|
||||||
|
wavhdr.bitsPerSample = 16;
|
||||||
|
|
||||||
|
sample_byte_size = ((wavhdr.bitsPerSample*wavhdr.NumOfChan)/8);
|
||||||
|
|
||||||
|
w_io->sample_byte_size = sample_byte_size;
|
||||||
|
|
||||||
|
wavhdr.bytesPerSec = ((samplerate*wavhdr.bitsPerSample)/8) * wavhdr.NumOfChan;
|
||||||
|
wavhdr.blockAlign = sample_byte_size;
|
||||||
|
memcpy((char*)&wavhdr.Subchunk2ID,"data",4);
|
||||||
|
|
||||||
|
wavhdr.ChunkSize = (w_io->total_nb_samples * sample_byte_size) + sizeof(wav_hdr) - 8;
|
||||||
|
wavhdr.Subchunk2Size = (w_io->total_nb_samples * sample_byte_size);
|
||||||
|
|
||||||
|
fwrite((void*)&wavhdr,sizeof(wav_hdr),1,w_io->file);
|
||||||
|
|
||||||
|
// Note about the following raw data format :
|
||||||
|
// 8-bit samples are stored as unsigned bytes, ranging from 0 to 255.
|
||||||
|
// 16-bit samples are stored as 2's-complement signed integers, ranging from -32768 to 32767.
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return w_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_wave(wave_io * w_io, void * buffer, int nbsamples)
|
||||||
|
{
|
||||||
|
if(w_io)
|
||||||
|
{
|
||||||
|
if(!w_io->file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fwrite(buffer,nbsamples * w_io->sample_byte_size,1, w_io->file);
|
||||||
|
w_io->total_nb_samples += nbsamples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_wave(wave_io * w_io)
|
||||||
|
{
|
||||||
|
wav_hdr wavhdr;
|
||||||
|
|
||||||
|
if(w_io)
|
||||||
|
{
|
||||||
|
if(!w_io->file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(w_io->type)
|
||||||
|
{
|
||||||
|
case WAVE_FILE_FORMAT_RAW_8BITS_IQ: // Raw / IQ
|
||||||
|
fclose(w_io->file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAVE_FILE_FORMAT_WAV_8BITS_STEREO: // Wave 8 bits stereo
|
||||||
|
case WAVE_FILE_FORMAT_WAV_16BITS_STEREO: // Wave 16 bits stereo
|
||||||
|
case WAVE_FILE_FORMAT_WAV_16BITS_MONO: // Wave 16 bits mono
|
||||||
|
fseek(w_io->file,0,SEEK_SET);
|
||||||
|
if(fread(&wavhdr,sizeof(wav_hdr),1,w_io->file) == 1)
|
||||||
|
{
|
||||||
|
wavhdr.ChunkSize += ( w_io->total_nb_samples * w_io->sample_byte_size );
|
||||||
|
wavhdr.Subchunk2Size += ( w_io->total_nb_samples * w_io->sample_byte_size );
|
||||||
|
|
||||||
|
fseek(w_io->file,0,SEEK_SET);
|
||||||
|
fwrite(&wavhdr,sizeof(wav_hdr),1,w_io->file);
|
||||||
|
}
|
||||||
|
fclose(w_io->file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(w_io);
|
||||||
|
}
|
||||||
|
}
|
68
src/common/wave.h
Normal file
68
src/common/wave.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
|
||||||
|
//----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
|
||||||
|
//---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
|
||||||
|
//--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
|
||||||
|
//-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
|
||||||
|
//-------------------------------------------------------------------------------//
|
||||||
|
//----------------------------------------------------- http://hxc2001.free.fr --//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// File : wave.h
|
||||||
|
// Contains: wave file helpers
|
||||||
|
//
|
||||||
|
// This file is part of rf-tools.
|
||||||
|
//
|
||||||
|
// Written by: Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// Copyright (C) 2022 Jean-François DEL NERO
|
||||||
|
//
|
||||||
|
// You are free to do what you want with this code.
|
||||||
|
// A credit is always appreciated if you use it into your product :)
|
||||||
|
//
|
||||||
|
// Change History (most recent first):
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __WAVE_H__
|
||||||
|
#define __WAVE_H__
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct wav_hdr_ //
|
||||||
|
{
|
||||||
|
char RIFF[4]; // RIFF Header
|
||||||
|
int ChunkSize; // RIFF Chunk Size
|
||||||
|
char WAVE[4]; // WAVE Header
|
||||||
|
char fmt[4]; // FMT header
|
||||||
|
int Subchunk1Size; // Size of the fmt chunk
|
||||||
|
short int AudioFormat; // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
|
||||||
|
short int NumOfChan; // Number of channels 1=Mono 2=Stereo
|
||||||
|
int SamplesPerSec; // Sampling Frequency in Hz
|
||||||
|
int bytesPerSec; // bytes per second */
|
||||||
|
short int blockAlign; // 2=16-bit mono, 4=16-bit stereo
|
||||||
|
short int bitsPerSample; // Number of bits per sample
|
||||||
|
char Subchunk2ID[4]; // "data" string
|
||||||
|
int Subchunk2Size; // Sampled data length
|
||||||
|
}wav_hdr;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
typedef struct wave_io_
|
||||||
|
{
|
||||||
|
FILE * file;
|
||||||
|
int type;
|
||||||
|
int total_nb_samples;
|
||||||
|
int sample_byte_size;
|
||||||
|
}wave_io;
|
||||||
|
|
||||||
|
#define WAVE_FILE_FORMAT_RAW_8BITS_IQ 0
|
||||||
|
#define WAVE_FILE_FORMAT_WAV_8BITS_STEREO 1
|
||||||
|
#define WAVE_FILE_FORMAT_WAV_16BITS_STEREO 2
|
||||||
|
#define WAVE_FILE_FORMAT_WAV_16BITS_MONO 3
|
||||||
|
|
||||||
|
wave_io * create_wave(char * path,int samplerate,int type);
|
||||||
|
void write_wave(wave_io * w_io, void * buffer, int nbsamples);
|
||||||
|
void close_wave(wave_io * w_io);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user