Skip to content

Commit 448d9dd

Browse files
committed
48<->8 resampler working again, inclusing test
1 parent 39e1bdd commit 448d9dd

File tree

7 files changed

+207
-22
lines changed

7 files changed

+207
-22
lines changed

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,14 @@ if(UNITTEST)
378378
")
379379
set_tests_properties(test_fdmdv_16to8_short PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
380380

381+
# 48<->8 kHz float resamplers
382+
add_test(NAME test_fdmdv_48to8
383+
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/octave;
384+
${CMAKE_CURRENT_BINARY_DIR}/unittest/t48_8;
385+
DISPLAY=\"\" echo \"diff_fft_mag('in8.raw','out8.raw'); quit;\" | octave-cli -qf
386+
")
387+
set_tests_properties(test_fdmdv_48to8 PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
388+
381389
add_test(NAME test_CML_ldpcut
382390
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/octave; SHORT_VERSION_FOR_CTEST=1 octave-cli -qf ldpcut.m")
383391
set_tests_properties(test_CML_ldpcut PROPERTIES PASS_REGULAR_EXPRESSION "Nerr: 0")

src/codec2_fdmdv.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,18 @@ extern "C" {
6767
#define FDMDV_SCALE 750 /* suggested scaling for 16 bit shorts */
6868
#define FDMDV_FCENTRE 1500 /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */
6969

70-
/* 8 to 48 kHz sample rate conversion */
70+
/* 8 to 18 kHz sample rate conversion */
7171

7272
#define FDMDV_OS 2 /* oversampling rate */
7373
#define FDMDV_OS_TAPS_16K 48 /* number of OS filter taps at 16kHz */
7474
#define FDMDV_OS_TAPS_8K (FDMDV_OS_TAPS_16K/FDMDV_OS) /* number of OS filter taps at 8kHz */
7575

76+
/* 8 to 48 kHz sample rate conversion */
77+
78+
#define FDMDV_OS_48 6 /* oversampling rate */
79+
#define FDMDV_OS_TAPS_48K 48 /* number of OS filter taps at 48kHz */
80+
#define FDMDV_OS_TAPS_48_8K (FDMDV_OS_TAPS_48K/FDMDV_OS_48) /* number of OS filter taps at 8kHz */
81+
7682
/* FDMDV states and stats structures */
7783

7884
struct FDMDV;
@@ -97,6 +103,10 @@ void fdmdv_8_to_16(float out16k[], float in8k[], int n);
97103
void fdmdv_8_to_16_short(short out16k[], short in8k[], int n);
98104
void fdmdv_16_to_8(float out8k[], float in16k[], int n);
99105
void fdmdv_16_to_8_short(short out8k[], short in16k[], int n);
106+
void fdmdv_8_to_48(float out48k[], float in8k[], int n);
107+
void fdmdv_48_to_8(float out8k[], float in48k[], int n);
108+
void fdmdv_8_to_48_short(short out48k[], short in8k[], int n);
109+
void fdmdv_48_to_8_short(short out8k[], short in48k[], int n);
100110

101111
void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin);
102112

src/fdmdv.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,119 @@ void fdmdv_16_to_8_short(short out8k[], short in16k[], int n)
18691869
}
18701870

18711871

1872+
/*---------------------------------------------------------------------------*\
1873+
1874+
FUNCTION....: fdmdv_8_to_48()
1875+
AUTHOR......: David Rowe
1876+
DATE CREATED: 9 May 2012
1877+
1878+
Changes the sample rate of a signal from 8 to 48 kHz.
1879+
1880+
n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n samples
1881+
at the 48 kHz rate. A memory of FDMDV_OS_TAPS_48/FDMDV_OS samples is reqd for
1882+
in8k[] (see t48_8.c unit test as example).
1883+
1884+
\*---------------------------------------------------------------------------*/
1885+
1886+
void fdmdv_8_to_48(float out48k[], float in8k[], int n)
1887+
{
1888+
int i,j,k,l;
1889+
1890+
/* make sure n is an integer multiple of the oversampling rate, ow
1891+
this function breaks */
1892+
1893+
assert((n % FDMDV_OS_48) == 0);
1894+
1895+
for(i=0; i<n; i++) {
1896+
for(j=0; j<FDMDV_OS_48; j++) {
1897+
out48k[i*FDMDV_OS_48+j] = 0.0;
1898+
for(k=0,l=0; k<FDMDV_OS_TAPS_48K; k+=FDMDV_OS_48,l++)
1899+
out48k[i*FDMDV_OS_48+j] += fdmdv_os_filter48[k+j]*in8k[i-l];
1900+
out48k[i*FDMDV_OS_48+j] *= FDMDV_OS_48;
1901+
1902+
}
1903+
}
1904+
1905+
/* update filter memory */
1906+
1907+
for(i=-FDMDV_OS_TAPS_48_8K; i<0; i++)
1908+
in8k[i] = in8k[i + n];
1909+
}
1910+
1911+
void fdmdv_8_to_48_short(short out48k[], short in8k[], int n)
1912+
{
1913+
int i,j,k,l;
1914+
float acc;
1915+
1916+
/* make sure n is an integer multiple of the oversampling rate, ow
1917+
this function breaks */
1918+
1919+
assert((n % FDMDV_OS_48) == 0);
1920+
1921+
for(i=0; i<n; i++) {
1922+
for(j=0; j<FDMDV_OS_48; j++) {
1923+
acc = 0.0;
1924+
for(k=0,l=0; k<FDMDV_OS_TAPS_48K; k+=FDMDV_OS_48,l++)
1925+
out48k[i*FDMDV_OS_48+j] += fdmdv_os_filter48[k+j]*in8k[i-l];
1926+
out48k[i*FDMDV_OS_48+j] = acc*FDMDV_OS_48;
1927+
1928+
}
1929+
}
1930+
1931+
/* update filter memory */
1932+
1933+
for(i=-FDMDV_OS_TAPS_48_8K; i<0; i++)
1934+
in8k[i] = in8k[i + n];
1935+
}
1936+
1937+
/*---------------------------------------------------------------------------*\
1938+
1939+
FUNCTION....: fdmdv_48_to_8()
1940+
AUTHOR......: David Rowe
1941+
DATE CREATED: 9 May 2012
1942+
1943+
Changes the sample rate of a signal from 48 to 8 kHz.
1944+
1945+
n is the number of samples at the 8 kHz rate, there are FDMDV_OS_48*n
1946+
samples at the 48 kHz rate. As above however a memory of
1947+
FDMDV_OS_TAPS_48 samples is reqd for in48k[] (see t48_8.c unit test as example).
1948+
1949+
\*---------------------------------------------------------------------------*/
1950+
1951+
void fdmdv_48_to_8(float out8k[], float in48k[], int n)
1952+
{
1953+
int i,j;
1954+
1955+
for(i=0; i<n; i++) {
1956+
out8k[i] = 0.0;
1957+
for(j=0; j<FDMDV_OS_TAPS_48K; j++)
1958+
out8k[i] += fdmdv_os_filter48[j]*in48k[i*FDMDV_OS_48-j];
1959+
}
1960+
1961+
/* update filter memory */
1962+
1963+
for(i=-FDMDV_OS_TAPS_48K; i<0; i++)
1964+
in48k[i] = in48k[i + n*FDMDV_OS_48];
1965+
}
1966+
1967+
void fdmdv_48_to_8_short(short out8k[], short in48k[], int n)
1968+
{
1969+
int i,j;
1970+
float acc;
1971+
1972+
for(i=0; i<n; i++) {
1973+
acc = 0.0;
1974+
for(j=0; j<FDMDV_OS_TAPS_48K; j++)
1975+
acc += fdmdv_os_filter48[j]*in48k[i*FDMDV_OS_48-j];
1976+
out8k[i] = acc;
1977+
}
1978+
1979+
/* update filter memory */
1980+
1981+
for(i=-FDMDV_OS_TAPS_48K; i<0; i++)
1982+
in48k[i] = in48k[i + n*FDMDV_OS_48];
1983+
}
1984+
18721985
/*---------------------------------------------------------------------------*\
18731986
18741987
Function used during development to test if magnitude of digital

src/os.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,56 @@ static const float fdmdv_os_filter[]= {
5151
-0.0008215855034550383
5252
};
5353

54+
/* Generate using fir1(47,1/6) in Octave */
55+
56+
static const float fdmdv_os_filter48[]= {
57+
-3.55606818e-04,
58+
-8.98615286e-04,
59+
-1.40119781e-03,
60+
-1.71713852e-03,
61+
-1.56471179e-03,
62+
-6.28128960e-04,
63+
1.24522223e-03,
64+
3.83138676e-03,
65+
6.41309478e-03,
66+
7.85893186e-03,
67+
6.93514929e-03,
68+
2.79361991e-03,
69+
-4.51051400e-03,
70+
-1.36671853e-02,
71+
-2.21034939e-02,
72+
-2.64084653e-02,
73+
-2.31425052e-02,
74+
-9.84218694e-03,
75+
1.40648474e-02,
76+
4.67316298e-02,
77+
8.39615986e-02,
78+
1.19925275e-01,
79+
1.48381174e-01,
80+
1.64097819e-01,
81+
1.64097819e-01,
82+
1.48381174e-01,
83+
1.19925275e-01,
84+
8.39615986e-02,
85+
4.67316298e-02,
86+
1.40648474e-02,
87+
-9.84218694e-03,
88+
-2.31425052e-02,
89+
-2.64084653e-02,
90+
-2.21034939e-02,
91+
-1.36671853e-02,
92+
-4.51051400e-03,
93+
2.79361991e-03,
94+
6.93514929e-03,
95+
7.85893186e-03,
96+
6.41309478e-03,
97+
3.83138676e-03,
98+
1.24522223e-03,
99+
-6.28128960e-04,
100+
-1.56471179e-03,
101+
-1.71713852e-03,
102+
-1.40119781e-03,
103+
-8.98615286e-04,
104+
-3.55606818e-04
105+
};
106+

unittest/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,5 @@ target_link_libraries(t16_8 codec2)
9090
add_executable(t16_8_short t16_8_short.c ../src/fdmdv.c ../src/kiss_fft.c)
9191
target_link_libraries(t16_8_short codec2)
9292

93+
add_executable(t48_8 t48_8.c ../src/fdmdv.c ../src/kiss_fft.c)
94+
target_link_libraries(t48_8 codec2)

unittest/t16_8.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ int main() {
6868
#endif
6969
#ifdef SINE
7070
for(i=0; i<N8; i++,t++)
71-
in8k[FDMDV_OS_TAPS_8K+i] = 16000.0*cos(TWO_PI*t*freq/FS);
71+
in8k[FDMDV_OS_TAPS_8K+i] = 16000.0*cos(TWO_PI*t*freq/(FS/FDMDV_OS));
7272
#endif
7373
for(i=0; i<N8; i++)
7474
in8k_short[i] = (short)in8k[i];

misc/t48_8.c renamed to unittest/t48_8.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,26 @@
2222
#include <stdio.h>
2323
#include "codec2_fdmdv.h"
2424

25-
#define N8 160 /* procssing buffer size at 8 kHz */
26-
#define N48 (N8*FDMDV_OS)
27-
#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
28-
#define FRAMES 50
29-
#define TWO_PI 6.283185307
30-
#define FS 8000
25+
#define N8 180 /* processing buffer size at 8 kHz */
26+
#define N48 (N8*FDMDV_OS_48)
27+
#define MEM8 FDMDV_OS_TAPS_48_8K
28+
#define FRAMES 50
29+
#define TWO_PI 6.283185307
30+
#define FS 48000
3131

3232
#define SINE
3333

3434
int main() {
3535
float in8k[MEM8 + N8];
36+
short in8k_short[N8];
3637
float out48k[N48];
3738
short out48k_short[N48];
3839
FILE *f48;
3940

40-
float in48k[FDMDV_OS_TAPS + N48];
41+
float in48k[FDMDV_OS_TAPS_48K + N48];
4142
float out8k[N48];
4243
short out8k_short[N8];
43-
FILE *f8;
44+
FILE *f8, *f8in;
4445

4546
int i,f,t,t1;
4647
float freq = 800.0;
@@ -49,12 +50,14 @@ int main() {
4950
assert(f48 != NULL);
5051
f8 = fopen("out8.raw", "wb");
5152
assert(f8 != NULL);
53+
f8in = fopen("in8.raw", "wb");
54+
assert(f8in != NULL);
5255

5356
/* clear filter memories */
5457

5558
for(i=0; i<MEM8; i++)
5659
in8k[i] = 0.0;
57-
for(i=0; i<FDMDV_OS_TAPS; i++)
60+
for(i=0; i<FDMDV_OS_TAPS_48K; i++)
5861
in48k[i] = 0.0;
5962

6063
t = t1 = 0;
@@ -66,16 +69,15 @@ int main() {
6669
#endif
6770
#ifdef SINE
6871
for(i=0; i<N8; i++,t++)
69-
in8k[MEM8+i] = 16000.0*cos(TWO_PI*t*freq/FS);
72+
in8k[MEM8+i] = 16000.0*cos(TWO_PI*t*freq/(FS/FDMDV_OS_48));
7073
#endif
74+
for(i=0; i<N8; i++)
75+
in8k_short[i] = (short)in8k[i];
76+
fwrite(in8k_short, sizeof(short), N8, f8in);
7177

7278
/* upsample */
7379

7480
fdmdv_8_to_48(out48k, &in8k[MEM8], N8);
75-
/*
76-
for(i=0; i<MEM8; i++)
77-
in8k[i] = in8k[i+N8];
78-
*/
7981

8082
/* save 48k to disk for plotting and check out */
8183

@@ -87,15 +89,11 @@ int main() {
8789
knock this out */
8890

8991
for(i=0; i<N48; i++,t1++)
90-
in48k[i+FDMDV_OS_TAPS] = out48k[i] + 16000.0*cos(TWO_PI*t1*1E4/FS);
92+
in48k[i+FDMDV_OS_TAPS_48K] = out48k[i] + 16000.0*cos(TWO_PI*t1*1E4/FS);
9193

9294
/* downsample */
9395

94-
fdmdv_48_to_8(out8k, &in48k[FDMDV_OS_TAPS], N8);
95-
/*
96-
for(i=0; i<FDMDV_OS_TAPS; i++)
97-
in48k[i] = in48k[i+N48];
98-
*/
96+
fdmdv_48_to_8(out8k, &in48k[FDMDV_OS_TAPS_48K], N8);
9997

10098
/* save 8k to disk for plotting and check out */
10199

@@ -107,6 +105,7 @@ int main() {
107105

108106
fclose(f48);
109107
fclose(f8);
108+
fclose(f8in);
110109
return 0;
111110

112111
}

0 commit comments

Comments
 (0)