diff --git a/.vscode/.server-controller-port.log b/.vscode/.server-controller-port.log index 1ffa33a..2d950a0 100644 --- a/.vscode/.server-controller-port.log +++ b/.vscode/.server-controller-port.log @@ -1,5 +1,5 @@ { "port": 13452, - "time": 1741953769473, + "time": 1742112482618, "version": "0.0.3" } \ No newline at end of file diff --git a/gen_wave.py b/gen_wave.py index f91b75d..347b588 100644 --- a/gen_wave.py +++ b/gen_wave.py @@ -6,7 +6,7 @@ import io, os if PLOT: import matplotlib.pyplot as plt if FFT: import numpy as np # Import numpy for FFT -sample_rate = 9500 +sample_rate = 11875 # this is modified from ChristopheJacquet's pydemod def rrcosfilter(NumSamples): @@ -57,9 +57,9 @@ outc.write(header) outh.write(header) def generate(): - offset = int(sample_rate*0.004) # 190 khz = 760 - count = int(offset / 10**(len(str(offset)) - 1)) # 760 / 100 = 7 - l = int(sample_rate / 1187.5) // 2 # 16/2 = 8 + offset = int(sample_rate*0.004) + count = int(offset / 10**(len(str(offset)) - 1)) + l = int(sample_rate / 1187.5) // 2 if count*l > l*16: raise Exception("Sample rate too small") print(f"{offset=} {count=} {l=}") @@ -67,13 +67,11 @@ def generate(): sample[l] = 1 sample[2*l] = -1 - # Apply the data-shaping filter sf = rrcosfilter(l*16) shapedSamples = convolve(sample, sf) - # Slice the array like numpy would out = shapedSamples[offset-l*count:offset+l*count] - out = [i/(max(out)) for i in out] + out = [2 * (i - min(out)) / (max(out) - min(out)) - 1 for i in out] if max(out) > 1 or min(out) < -1: raise Exception("Clipped") if PLOT: @@ -92,6 +90,7 @@ def generate(): # Plot the magnitude of the FFT plt.figure(figsize=(10, 6)) plt.plot(fft_freqs[:N//2], np.abs(fft_out)[:N//2]) # Plot only the positive frequencies + plt.xlim(0,1187.5*3) plt.title("FFT of the waveform") plt.xlabel("Frequency (Hz)") plt.ylabel("Magnitude") diff --git a/gen_wave_original.py b/gen_wave_original.py new file mode 100644 index 0000000..0f7bf18 --- /dev/null +++ b/gen_wave_original.py @@ -0,0 +1,109 @@ +PLOT = True +FFT = PLOT and True + +import math +import io, os +if PLOT: import matplotlib.pyplot as plt +if FFT: import numpy as np # Import numpy for FFT + +sample_rate = 190000 + +# this is modified from ChristopheJacquet's pydemod +def rrcosfilter(NumSamples): + T_delta = 1/float(sample_rate) + sample_num = list(range(NumSamples)) + h_rrc = [0.0] * NumSamples + SymbolPeriod = 1/(2*1187.5) + + for x in sample_num: + t = (x-NumSamples/2)*T_delta + if t == 0.0: + h_rrc[x] = 1.0 - 1 + (4/math.pi) + elif t == SymbolPeriod/4: + h_rrc[x] = (1/math.sqrt(2))*(((1+2/math.pi)* \ + (math.sin(math.pi/4))) + ((1-2/math.pi)*(math.cos(math.pi/4)))) + elif t == -SymbolPeriod/4: + h_rrc[x] = (1/math.sqrt(2))*(((1+2/math.pi)* \ + (math.sin(math.pi/4))) + ((1-2/math.pi)*(math.cos(math.pi/4)))) + else: + h_rrc[x] = (4*(t/SymbolPeriod)*math.cos(math.pi*t*2/SymbolPeriod))/ \ + (math.pi*t*(1-(4*t/SymbolPeriod)*(4*t/SymbolPeriod))/SymbolPeriod) + + return h_rrc + +def convolve(a, b): + out = [0] * (len(a) + len(b) - 1) + for i in range(len(a)): + for j in range(len(b)): + out[i+j] += a[i] * b[j] + return out + +PATH = os.path.dirname(os.path.abspath(__file__)) + +outc = io.open(f"{PATH}/src/waveforms.c", mode="w", encoding="utf8") +outh = io.open(f"{PATH}/src/waveforms.h", mode="w", encoding="utf8") + +header = u""" +/* This file was automatically generated by "gen_wave.py". + (C) 2014 Christophe Jacquet. + (C) 2023 Anthony96922. + (C) 2025 kuba201. + Released under the GNU GPL v3 license. +*/ + +""" + +outc.write(header) +outh.write(header) + +def generate(): + offset = 760 + count = 7 + l = int(sample_rate / 1187.5) // 2 + if count*l > l*16: raise Exception("Sample rate too small") + print(f"{offset=} {count=} {l=}") + + sample = [0.0] * (count*l) + sample[l] = 1 + sample[2*l] = -1 + + sf = rrcosfilter(l*16) + shapedSamples = convolve(sample, sf) + + out = shapedSamples[offset-l*count:offset+l*count] + out = [2 * (i - min(out)) / (max(out) - min(out)) - 1 for i in out] + if max(out) > 1 or min(out) < -1: raise Exception("Clipped") + + if PLOT: + # Plot the waveform + plt.plot(out, label="out") + plt.legend() + plt.grid(True) + plt.show() + + if FFT: + # Compute the FFT of the waveform + N = len(out) + fft_out = np.fft.fft(out) + fft_freqs = np.fft.fftfreq(N, d=1/sample_rate) + + # Plot the magnitude of the FFT + plt.figure(figsize=(10, 6)) + plt.plot(fft_freqs[:N//2], np.abs(fft_out)[:N//2]) # Plot only the positive frequencies + plt.xlim(0,1187.5*3) + plt.title("FFT of the waveform") + plt.xlabel("Frequency (Hz)") + plt.ylabel("Magnitude") + plt.grid(True) + plt.show() + + # outc.write(u"float waveform_biphase[{size}] = {{{values}}};\n\n".format( + # values = u", ".join(map(str, out)), + # size = len(out))) + + # outh.write(u"extern float waveform_biphase[{size}];\n".format(size=len(out))) + +generate() + +outc.close() +outh.close() \ No newline at end of file diff --git a/src/rds.h b/src/rds.h index 84f2f12..90dec8a 100644 --- a/src/rds.h +++ b/src/rds.h @@ -10,9 +10,10 @@ #define GROUP_LENGTH 4 #define BITS_PER_GROUP (GROUP_LENGTH * (BLOCK_SIZE + POLY_DEG)) -#define RDS_SAMPLE_RATE 9500 -#define SAMPLES_PER_BIT 8 // (1/1187.5)*RDS_SAMPLE_RATE -#define FILTER_SIZE 24 +// when i say ratio 10, i mean 1187.5*10 +#define RDS_SAMPLE_RATE 11875 // pira's m32 works at 361 khz, which is a ratio of 304, but this does a ratio of 10, while the m232 does a ratio of about 500 +#define SAMPLES_PER_BIT 10 // (1/1187.5)*RDS_SAMPLE_RATE or RDS_SAMPLE_RATE/1187.5, to check you can do (1187.5*SAMPLES_PER_BIT)=(RDS_SAMPLE_RATE) +#define FILTER_SIZE 40 #define SAMPLE_BUFFER_SIZE (SAMPLES_PER_BIT + FILTER_SIZE) #define RT_LENGTH 64 diff --git a/src/waveforms.c b/src/waveforms.c index 64178c6..6beb162 100644 --- a/src/waveforms.c +++ b/src/waveforms.c @@ -6,5 +6,5 @@ Released under the GNU GPL v3 license. */ -float waveform_biphase[24] = {0.004662004662004664, -1.192872569837455e-17, -0.008325008325008324, 5.168171209081069e-17, 0.017316017316017313, -4.0195812562580885e-17, -0.04761904761904761, -2.153908398182045e-17, 0.2857142857142856, 0.7363107781851077, 1.0, 0.7363107781851077, 0.0, -0.7363107781851077, -1.0, -0.7363107781851077, -0.2857142857142856, 2.153908398182045e-17, 0.04761904761904761, 4.0195812562580885e-17, -0.017316017316017313, -5.168171209081069e-17, 0.008325008325008324, 1.192872569837455e-17}; +float waveform_biphase[40] = {0.001428519781289772, 0.0016664760371696286, -0.0007489747210579489, -0.002879473467708782, -0.00106869603307147, 0.003402376491623338, 0.004197098675717825, -0.0020108774820242203, -0.008325008325008265, -0.003370279435959911, 0.011902549863605172, 0.016661972622002308, -0.009354493372215611, -0.04761904761904756, -0.02565484871607826, 0.14035864022832323, 0.4612061004721879, 0.817876195033512, 1.0, 0.8360849414906586, 0.3268491412309902, -0.3268491412309902, -0.8360849414906588, -1.0, -0.817876195033512, -0.461206100472188, -0.14035864022832323, 0.02565484871607837, 0.04761904761904745, 0.009354493372215611, -0.016661972622002308, -0.011902549863605172, 0.0033702794359598, 0.008325008325008376, 0.0020108774820242203, -0.004197098675717825, -0.003402376491623449, 0.00106869603307147, 0.002879473467708893, 0.00074897472105806}; diff --git a/src/waveforms.h b/src/waveforms.h index c657cad..536f157 100644 --- a/src/waveforms.h +++ b/src/waveforms.h @@ -6,4 +6,4 @@ Released under the GNU GPL v3 license. */ -extern float waveform_biphase[24]; +extern float waveform_biphase[40];