Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
colorEagleStdio
taskbus
提交
75d5536f
taskbus
项目概览
colorEagleStdio
/
taskbus
通知
159
Star
11
Fork
3
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
taskbus
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
75d5536f
编写于
4月 18, 2022
作者:
M
manjaro-xfce
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
添加分数倍采样率变换模块
上级
0c6fdfcf
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
950 addition
and
6 deletion
+950
-6
modules/modules.pro
modules/modules.pro
+3
-1
modules/transforms/CMakeLists.txt
modules/transforms/CMakeLists.txt
+1
-0
modules/transforms/filter_fir/main.cpp
modules/transforms/filter_fir/main.cpp
+1
-1
modules/transforms/resample_pqfraction/CMakeLists.txt
modules/transforms/resample_pqfraction/CMakeLists.txt
+26
-0
modules/transforms/resample_pqfraction/main.cpp
modules/transforms/resample_pqfraction/main.cpp
+398
-0
modules/transforms/resample_pqfraction/resample.h
modules/transforms/resample_pqfraction/resample.h
+189
-0
modules/transforms/resample_pqfraction/resample_pqfraction.json
...s/transforms/resample_pqfraction/resample_pqfraction.json
+59
-0
modules/transforms/resample_pqfraction/resample_pqfraction.pro
...es/transforms/resample_pqfraction/resample_pqfraction.pro
+12
-0
modules/transforms/resample_pqfraction/resample_pqfraction.qrc
...es/transforms/resample_pqfraction/resample_pqfraction.qrc
+5
-0
modules/transforms/resample_pqfraction/upfirdn.h
modules/transforms/resample_pqfraction/upfirdn.h
+252
-0
modules/uhd/uhd_usrp_continous/uhd_io_continous.cpp
modules/uhd/uhd_usrp_continous/uhd_io_continous.cpp
+2
-2
modules/uhd/uhd_usrp_io/uhd_io.cpp
modules/uhd/uhd_usrp_io/uhd_io.cpp
+2
-2
未找到文件。
modules/modules.pro
浏览文件 @
75d5536f
TEMPLATE
=
subdirs
TEMPLATE
=
subdirs
#
main
framework
project
#
main
framework
project
SUBDIRS
+=
sources
/
source_plutosdr
\
SUBDIRS
+=
\
sources
/
source_plutosdr
\
transforms
/
transform_fft
\
transforms
/
transform_fft
\
transforms
/
mod_fm
\
transforms
/
mod_fm
\
transforms
/
filter_fir
\
transforms
/
filter_fir
\
transforms
/
resample_pqfraction
\
sources
/
source_files
\
sources
/
source_files
\
sinks
/
sink_file
\
sinks
/
sink_file
\
sinks
/
sink_plutosdr
\
sinks
/
sink_plutosdr
\
...
...
modules/transforms/CMakeLists.txt
浏览文件 @
75d5536f
...
@@ -3,3 +3,4 @@ cmake_minimum_required(VERSION 3.5)
...
@@ -3,3 +3,4 @@ cmake_minimum_required(VERSION 3.5)
add_subdirectory
(
mod_fm
)
add_subdirectory
(
mod_fm
)
add_subdirectory
(
transform_fft
)
add_subdirectory
(
transform_fft
)
add_subdirectory
(
filter_fir
)
add_subdirectory
(
filter_fir
)
add_subdirectory
(
resample_pqfraction
)
modules/transforms/filter_fir/main.cpp
浏览文件 @
75d5536f
...
@@ -76,7 +76,7 @@ int do_fir(const cmdlineParser & args)
...
@@ -76,7 +76,7 @@ int do_fir(const cmdlineParser & args)
const
unsigned
int
iinput
=
args
.
toInt
(
"in"
,
0
);
const
unsigned
int
iinput
=
args
.
toInt
(
"in"
,
0
);
const
unsigned
int
i_tmin
=
args
.
toInt
(
"in_time"
,
0
);
const
unsigned
int
i_tmin
=
args
.
toInt
(
"in_time"
,
0
);
const
unsigned
int
i_tmout
=
args
.
toInt
(
"out_time"
,
0
);
const
unsigned
int
i_tmout
=
args
.
toInt
(
"out_time"
,
0
);
const
double
iout
=
args
.
toInt
(
"out"
,
0
);
const
int
iout
=
args
.
toInt
(
"out"
,
0
);
std
::
vector
<
double
>
hn
=
args
.
toDoubleArray
(
"hn"
);
std
::
vector
<
double
>
hn
=
args
.
toDoubleArray
(
"hn"
);
//工作模式
//工作模式
const
int
sptype
=
args
.
toInt
(
"sptype"
,
0
);
fprintf
(
stderr
,
"sptype is %d."
,
sptype
);
const
int
sptype
=
args
.
toInt
(
"sptype"
,
0
);
fprintf
(
stderr
,
"sptype is %d."
,
sptype
);
...
...
modules/transforms/resample_pqfraction/CMakeLists.txt
0 → 100644
浏览文件 @
75d5536f
cmake_minimum_required
(
VERSION 3.5
)
set
(
CMAKE_INCLUDE_CURRENT_DIR ON
)
set
(
CMAKE_AUTOUIC ON
)
set
(
CMAKE_AUTOMOC ON
)
set
(
CMAKE_AUTORCC ON
)
set
(
CMAKE_CXX_STANDARD 17
)
set
(
CMAKE_CXX_STANDARD_REQUIRED ON
)
find_package
(
QT NAMES Qt6 COMPONENTS Core REQUIRED
)
find_package
(
Qt
${
QT_VERSION_MAJOR
}
COMPONENTS Core REQUIRED
)
include_directories
(
${
TASKBUS_INTERFACEDIR
}
)
set
(
PRJ_SOURCES
resample.h
upfirdn.h
main.cpp
resample_pqfraction.qrc
)
#############Target======================
add_executable
(
resample_pqfraction
${
PRJ_SOURCES
}
)
target_link_libraries
(
resample_pqfraction Qt
${
QT_VERSION_MAJOR
}
::Core
)
modules/transforms/resample_pqfraction/main.cpp
0 → 100644
浏览文件 @
75d5536f
#
include
<
QCoreApplication
>
#include <QVector>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <string>
#include <memory>
#include <QFile>
#include "cmdlineparser.h"
#include "tb_interface.h"
#include "resample.h"
using
namespace
TASKBUS
;
const
int
OFFLINEDEBUG
=
0
;
//数据源方法
int
do_resample
(
const
cmdlineParser
&
args
);
//全局的终止标记
static
bool
bfinished
=
false
;
using
namespace
std
;
int
main
(
int
argc
,
char
*
argv
[])
{
QCoreApplication
a
(
argc
,
argv
);
//重要!设置输入输出为二进制!
init_client
();
//解释命令行
cmdlineParser
args
;
if
(
OFFLINEDEBUG
==
0
)
args
.
parser
(
argc
,
argv
);
else
{
FILE
*
old_stdin
,
*
old_stdout
;
auto
ars
=
debug
(
"/home/user/codes/build-taskbus-linux-Release/bin/debug/pid7852/"
,
&
old_stdin
,
&
old_stdout
);
args
.
parser
(
ars
);
}
int
ret
=
0
;
//每个模块要响应 --information参数,打印自己的功能定义字符串。或者提供一个json文件。
if
(
args
.
contains
(
"information"
))
{
QFile
fp
(
":/resample_pqfraction.json"
);
if
(
fp
.
open
(
QIODevice
::
ReadOnly
)
==
false
)
{
fp
.
setFileName
(
":/json/filter_fir.json"
);
fp
.
open
(
QIODevice
::
ReadOnly
);
}
if
(
fp
.
isOpen
())
{
QByteArray
arr
=
fp
.
readAll
();
arr
.
push_back
(
'\0'
);
puts
(
arr
.
constData
());
fflush
(
stdout
);
}
ret
=
0
;
}
else
if
(
args
.
contains
(
"function"
/*,"filter_fir"*/
))
//正常运行模式
{
ret
=
do_resample
(
args
);
}
else
{
fprintf
(
stderr
,
"Error:Function does not exits."
);
ret
=
-
1
;
}
return
ret
;
}
std
::
vector
<
float
>
input_f
[
2
],
output_f
[
2
];
std
::
vector
<
short
>
out_cache
;
int
kUpfactor
=
1
,
kDownfactor
=
2
;
unsigned
int
instance
=
0
;
unsigned
int
iinput
=
0
;
unsigned
int
i_tmin
=
0
;
unsigned
int
i_tmout
=
0
;
int
iout
=
0
;
unsigned
long
long
input_clk
=
0
,
output_clk
=
0
;
double
doutin_clock
=
0
,
doutin_ratio
=
1
;
std
::
map
<
unsigned
long
long
,
std
::
vector
<
unsigned
char
>
>
timestamp_vec
;
unsigned
long
long
next_timestamps
=
0
;
bool
tmstamp_exists
=
false
;
bool
tmstamp_begin
=
false
;
void
calc_resample
()
{
if
(
input_f
[
0
].
size
())
resample
<
float
>
(
kUpfactor
,
kDownfactor
,
input_f
[
0
],
output_f
[
0
]
);
if
(
input_f
[
1
].
size
())
resample
<
float
>
(
kUpfactor
,
kDownfactor
,
input_f
[
1
],
output_f
[
1
]
);
//缓存
const
int
sizei
=
output_f
[
0
].
size
();
const
int
sizeq
=
output_f
[
1
].
size
();
for
(
int
i
=
0
;
i
<
sizei
;
++
i
)
{
out_cache
.
push_back
(
output_f
[
0
][
i
]);
if
(
sizeq
)
out_cache
.
push_back
(
output_f
[
1
][
i
]);
}
output_f
[
0
].
clear
();
output_f
[
1
].
clear
();
}
void
broadresult
()
{
//缓存
bool
q_existed
=
input_f
[
1
].
size
()
?
true
:
false
;
const
int
spsize
=
q_existed
?
4
:
2
;
if
(
tmstamp_exists
)
{
int
sizei
=
out_cache
.
size
()
*
2
/
spsize
;
int
sizeq
=
out_cache
.
size
()
*
2
/
spsize
;
while
(
doutin_clock
+
sizei
*
doutin_ratio
>
next_timestamps
)
{
//保持时续的一一对应
long
long
commit_clk
=
output_clk
;
double
commit_dclk
=
doutin_clock
;
for
(
int
i
=
0
;
i
<
sizei
;
++
i
)
{
if
(
commit_dclk
>=
next_timestamps
)
{
if
(
iout
)
{
push_subject
(
iout
,
instance
,
i
*
spsize
,
(
unsigned
char
*
)
out_cache
.
data
()
);
out_cache
.
erase
(
out_cache
.
begin
(),
out_cache
.
begin
()
+
i
*
spsize
/
2
);
}
//播发老时戳的数据
if
(
i_tmout
&&
timestamp_vec
.
size
())
push_subject
(
i_tmout
,
instance
,
timestamp_vec
.
begin
()
->
second
.
size
(),
(
unsigned
char
*
)
timestamp_vec
.
begin
()
->
second
.
data
()
);
//新时戳
if
(
timestamp_vec
.
size
())
timestamp_vec
.
erase
(
timestamp_vec
.
begin
());
next_timestamps
=
-
1
;
//max
if
(
timestamp_vec
.
size
())
next_timestamps
=
timestamp_vec
.
begin
()
->
first
;
output_clk
=
commit_clk
;
doutin_clock
=
commit_dclk
;
break
;
}
++
commit_clk
;
commit_dclk
+=
doutin_ratio
;
}
sizei
=
out_cache
.
size
()
*
2
/
spsize
;
sizeq
=
out_cache
.
size
()
*
2
/
spsize
;
}
}
else
{
//播发
if
(
iout
)
{
push_subject
(
iout
,
instance
,
out_cache
.
size
()
*
2
,
(
unsigned
char
*
)
out_cache
.
data
()
);
}
out_cache
.
clear
();
}
}
int
do_resample
(
const
cmdlineParser
&
args
)
{
using
namespace
TASKBUS
;
int
res
=
0
;
//获得平台告诉自己的实例名
instance
=
args
.
toInt
(
"instance"
,
0
);
iinput
=
args
.
toInt
(
"in"
,
0
);
i_tmin
=
args
.
toInt
(
"in_time"
,
0
);
i_tmout
=
args
.
toInt
(
"out_time"
,
0
);
iout
=
args
.
toInt
(
"out"
,
0
);
const
int
np
=
args
.
toInt
(
"np"
,
2
);
const
int
nq
=
args
.
toInt
(
"nq"
,
1
);
//工作模式
const
int
sptype
=
args
.
toInt
(
"sptype"
,
0
);
fprintf
(
stderr
,
"sptype is %d."
,
sptype
);
int
type
=
args
.
toInt
(
"type"
,
1
);
if
(
type
<
0
||
type
>
1
)
type
=
0
;
fflush
(
stderr
);
//计算翻转倍数
kUpfactor
=
np
;
kDownfactor
=
nq
;
fprintf
(
stderr
,
"NP=%d,NQ=%d
\n
"
,
np
,
nq
);
doutin_ratio
=
1.0
*
kDownfactor
/
kUpfactor
;
int
nBatchSize
=
kDownfactor
;
while
(
nBatchSize
<
1000
)
nBatchSize
*=
2
;
input_f
[
0
].
resize
(
nBatchSize
);
if
(
type
==
1
)
input_f
[
1
].
resize
(
nBatchSize
);
try
{
//判断参数合法性
if
(
instance
==
0
)
throw
"function=quit;{
\"
error
\"
:
\"
instance is 0, quit.
\"
}"
;
int
failed_header
=
0
;
while
(
false
==
bfinished
)
{
subject_package_header
header
;
vector
<
unsigned
char
>
packagedta
=
pull_subject
(
&
header
);
if
(
is_valid_header
(
header
)
==
false
)
{
if
(
++
failed_header
>
16
)
bfinished
=
true
;
continue
;
}
if
(
is_control_subject
(
header
))
{
//收到命令进程退出的广播消息,退出
if
(
strstr
(
control_subject
(
header
,
packagedta
).
c_str
(),
"function=quit;"
)
!=
nullptr
)
bfinished
=
true
;
}
else
if
(
header
.
subject_id
==
i_tmin
&&
i_tmout
)
{
tmstamp_exists
=
true
;
if
(
!
tmstamp_begin
)
{
if
(
i_tmout
)
push_subject
(
i_tmout
,
instance
,
packagedta
.
size
(),
(
unsigned
char
*
)
packagedta
.
data
()
);
}
else
{
if
(
timestamp_vec
.
size
()
==
0
)
next_timestamps
=
input_clk
;
timestamp_vec
[
input_clk
]
=
std
::
move
(
packagedta
);
broadresult
();
}
tmstamp_begin
=
true
;
}
else
if
(
header
.
subject_id
==
iinput
)
{
//Input Buffer
switch
(
sptype
)
{
//Intel 16bit
case
0
:{
if
(
type
==
0
)
{
const
short
*
pdata
=
(
const
short
*
)
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
short
);
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
input_f
[
0
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
];
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
else
{
const
short
(
*
pdata
)[
2
]
=
(
const
short
(
*
)[
2
])
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
short
)
/
2
;
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
input_f
[
0
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
][
0
];
input_f
[
1
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
][
1
];
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
}
break
;
//16bit U
case
1
:{
if
(
type
==
0
)
{
const
unsigned
char
*
pdata
=
(
const
unsigned
char
*
)
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
short
);
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
unsigned
char
pt
[
2
]
=
{
pdata
[
spid
*
2
+
1
],
pdata
[
spid
*
2
]};
short
*
ptv
=
(
short
*
)
pt
;
input_f
[
0
][
input_clk
%
nBatchSize
]
=
*
ptv
;
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
else
{
const
unsigned
char
*
pdata
=
(
const
unsigned
char
*
)
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
short
)
/
2
;
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
unsigned
char
pt
[
2
][
2
]
=
{
{
pdata
[
spid
*
4
+
1
],
pdata
[
spid
*
4
]},
{
pdata
[
2
+
spid
*
4
+
1
],
pdata
[
2
+
spid
*
4
]}
};
short
*
ptv
[
2
]
=
{(
short
*
)
pt
[
0
],(
short
*
)
pt
[
1
]};
input_f
[
0
][
input_clk
%
nBatchSize
]
=
*
(
ptv
[
0
]);
input_f
[
1
][
input_clk
%
nBatchSize
]
=
*
(
ptv
[
1
]);
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
}
break
;
//int8
case
2
:{
if
(
type
==
0
)
{
const
char
*
pdata
=
(
const
char
*
)
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
char
);
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
input_f
[
0
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
];
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
else
{
const
char
(
*
pdata
)[
2
]
=
(
const
char
(
*
)[
2
])
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
char
)
/
2
;
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
input_f
[
0
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
][
0
];
input_f
[
1
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
][
1
];
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
}
break
;
case
3
:{
if
(
type
==
0
)
{
const
unsigned
char
*
pdata
=
(
const
unsigned
char
*
)
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
char
);
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
input_f
[
0
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
];
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
else
{
const
unsigned
(
*
pdata
)[
2
]
=
(
const
unsigned
(
*
)[
2
])
packagedta
.
data
();
const
int
samples
=
packagedta
.
size
()
/
sizeof
(
char
)
/
2
;
for
(
int
spid
=
0
;
spid
<
samples
;
++
spid
)
{
input_f
[
0
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
][
0
];
input_f
[
1
][
input_clk
%
nBatchSize
]
=
pdata
[
spid
][
1
];
++
input_clk
;
if
(
input_clk
%
nBatchSize
==
0
)
calc_resample
();
}
}
}
break
;
default:
break
;
}
if
(
!
tmstamp_exists
)
broadresult
();
}
}
}
catch
(
const
char
*
errMessage
)
{
//向所有部位广播,偶要退出。
push_subject
(
control_subect_id
(),
/*instance,broadcast_destin_id(),*/
0
,
errMessage
);
fprintf
(
stderr
,
"Error:%s."
,
errMessage
);
fflush
(
stderr
);
res
=
-
1
;
}
return
res
;
}
modules/transforms/resample_pqfraction/resample.h
0 → 100644
浏览文件 @
75d5536f
//RESAMPLE Change the sampling rate of a signal.
// Y = RESAMPLE(UpFactor, DownFactor, InputSignal, OutputSignal) resamples the sequence in
// vector InputSignal at UpFactor/DownFactor times and stores the resampled data to OutputSignal.
// OutputSignal is UpFactor/DownFactor times the length of InputSignal. UpFactor and DownFactor must be
// positive integers.
//This function is translated from Matlab's Resample funtion.
//Author: Haoqi Bai
#pragma once
#include <vector>
#include <cmath>
#include <numeric>
#include <algorithm>
#include "upfirdn.h"
using
std
::
vector
;
template
<
typename
T
>
T
sinc
(
T
x
)
{
if
(
std
::
abs
(
x
-
0.0
)
<
0.000001
)
return
1
;
return
std
::
sin
(
M_PI
*
x
)
/
(
M_PI
*
x
);
}
inline
int
quotientCeil
(
int
num1
,
int
num2
)
{
if
(
num1
%
num2
!=
0
)
return
num1
/
num2
+
1
;
return
num1
/
num2
;
}
template
<
typename
T
>
std
::
vector
<
T
>
firls
(
int
length
,
vector
<
T
>
freq
,
const
vector
<
T
>&
amplitude
)
{
int
freqSize
=
freq
.
size
();
int
weightSize
=
freqSize
/
2
;
vector
<
T
>
weight
(
weightSize
,
1.0
);
int
filterLength
=
length
+
1
;
for
(
auto
&
it
:
freq
)
it
/=
2.0
;
length
=
(
filterLength
-
1
)
/
2
;
bool
Nodd
=
filterLength
&
1
;
vector
<
T
>
k
(
length
+
1
);
std
::
iota
(
k
.
begin
(),
k
.
end
(),
0.0
);
if
(
!
Nodd
)
{
for
(
auto
&
it
:
k
)
it
+=
0.5
;
}
T
b0
=
0.0
;
if
(
Nodd
)
{
k
.
erase
(
k
.
begin
());
}
vector
<
T
>
b
(
k
.
size
(),
0.0
);
for
(
int
i
=
0
;
i
<
freqSize
;
i
+=
2
)
{
auto
Fi
=
freq
[
i
];
auto
Fip1
=
freq
[
i
+
1
];
auto
ampi
=
amplitude
[
i
];
auto
ampip1
=
amplitude
[
i
+
1
];
auto
wt2
=
std
::
pow
(
weight
[
i
/
2
],
2
);
auto
m_s
=
(
ampip1
-
ampi
)
/
(
Fip1
-
Fi
);
auto
b1
=
ampi
-
(
m_s
*
Fi
);
if
(
Nodd
)
{
b0
+=
(
b1
*
(
Fip1
-
Fi
))
+
m_s
/
2
*
(
std
::
pow
(
Fip1
,
2
)
-
std
::
pow
(
Fi
,
2
))
*
wt2
;
}
std
::
transform
(
b
.
begin
(),
b
.
end
(),
k
.
begin
(),
b
.
begin
(),
[
m_s
,
Fi
,
Fip1
,
wt2
](
T
b
,
T
k
)
{
return
b
+
(
m_s
/
(
4
*
std
::
pow
(
M_PI
,
2
))
*
(
std
::
cos
(
2
*
M_PI
*
Fip1
)
-
std
::
cos
(
2
*
M_PI
*
Fi
))
/
(
std
::
pow
(
k
,
2
)))
*
wt2
;});
std
::
transform
(
b
.
begin
(),
b
.
end
(),
k
.
begin
(),
b
.
begin
(),
[
m_s
,
Fi
,
Fip1
,
wt2
,
b1
](
T
b
,
T
k
)
{
return
b
+
(
Fip1
*
(
m_s
*
Fip1
+
b1
)
*
sinc
<
T
>
(
2
*
k
*
Fip1
)
-
Fi
*
(
m_s
*
Fi
+
b1
)
*
sinc
<
T
>
(
2
*
k
*
Fi
))
*
wt2
;});
}
if
(
Nodd
)
{
b
.
insert
(
b
.
begin
(),
b0
);
}
auto
w0
=
weight
[
0
];
vector
<
T
>
a
(
b
.
size
());
std
::
transform
(
b
.
begin
(),
b
.
end
(),
a
.
begin
(),
[
w0
](
T
b
)
{
return
std
::
pow
(
w0
,
2
)
*
4
*
b
;});
vector
<
T
>
result
=
{
a
.
rbegin
(),
a
.
rend
()};
decltype
(
a
.
begin
())
it
;
if
(
Nodd
)
{
it
=
a
.
begin
()
+
1
;
}
else
{
it
=
a
.
begin
();
}
result
.
insert
(
result
.
end
(),
it
,
a
.
end
());
for
(
auto
&
it
:
result
)
{
it
*=
0.5
;
}
return
result
;
}
template
<
typename
T
>
std
::
vector
<
T
>
kaiser
(
const
int
order
,
const
T
bta
)
{
T
Numerator
,
Denominator
;
Denominator
=
std
::
cyl_bessel_i
(
0
,
bta
);
auto
od2
=
(
static_cast
<
T
>
(
order
)
-
1
)
/
2
;
std
::
vector
<
T
>
window
;
window
.
reserve
(
order
);
for
(
int
n
=
0
;
n
<
order
;
n
++
)
{
auto
x
=
bta
*
std
::
sqrt
(
1
-
std
::
pow
((
n
-
od2
)
/
od2
,
2
));
Numerator
=
std
::
cyl_bessel_i
(
0
,
x
);
window
.
push_back
(
Numerator
/
Denominator
);
}
return
window
;
}
template
<
typename
T
>
void
resample
(
int
upFactor
,
int
downFactor
,
vector
<
T
>&
inputSignal
,
vector
<
T
>&
outputSignal
)
{
const
int
n
=
10
;
const
T
bta
=
5.0
;
if
(
upFactor
<=
0
||
downFactor
<=
0
)
throw
std
::
runtime_error
(
"factors must be positive integer"
);
int
gcd_o
=
std
::
gcd
(
upFactor
,
downFactor
);
upFactor
/=
gcd_o
;
downFactor
/=
gcd_o
;
if
(
upFactor
==
downFactor
)
{
outputSignal
=
inputSignal
;
return
;
}
int
inputSize
=
inputSignal
.
size
();
outputSignal
.
clear
();
int
outputSize
=
quotientCeil
(
inputSize
*
upFactor
,
downFactor
);
outputSignal
.
reserve
(
outputSize
);
int
maxFactor
=
std
::
max
(
upFactor
,
downFactor
);
T
firlsFreq
=
1.0
/
2.0
/
static_cast
<
T
>
(
maxFactor
);
int
length
=
2
*
n
*
maxFactor
+
1
;
vector
<
T
>
firlsFreqsV
=
{
0.0
,
2
*
firlsFreq
,
2
*
firlsFreq
,
1.0
};
vector
<
T
>
firlsAmplitudeV
=
{
1.0
,
1.0
,
0.0
,
0.0
};
vector
<
T
>
coefficients
=
firls
<
T
>
(
length
-
1
,
firlsFreqsV
,
firlsAmplitudeV
);
vector
<
T
>
window
=
kaiser
<
T
>
(
length
,
bta
);
int
coefficientsSize
=
coefficients
.
size
();
for
(
int
i
=
0
;
i
<
coefficientsSize
;
i
++
)
coefficients
[
i
]
*=
upFactor
*
window
[
i
];
int
lengthHalf
=
(
length
-
1
)
/
2
;
int
nz
=
downFactor
-
lengthHalf
%
downFactor
;
vector
<
T
>
h
;
h
.
reserve
(
coefficientsSize
+
nz
);
for
(
int
i
=
0
;
i
<
nz
;
i
++
)
h
.
push_back
(
0.0
);
for
(
int
i
=
0
;
i
<
coefficientsSize
;
i
++
)
h
.
push_back
(
coefficients
[
i
]
);
int
hSize
=
h
.
size
();
lengthHalf
+=
nz
;
int
delay
=
lengthHalf
/
downFactor
;
nz
=
0
;
while
(
quotientCeil
(
(
inputSize
-
1
)
*
upFactor
+
hSize
+
nz
,
downFactor
)
-
delay
<
outputSize
)
nz
++
;
for
(
int
i
=
0
;
i
<
nz
;
i
++
)
h
.
push_back
(
0.0
);
vector
<
T
>
y
;
upfirdn
(
upFactor
,
downFactor
,
inputSignal
,
h
,
y
);
for
(
int
i
=
delay
;
i
<
outputSize
+
delay
;
i
++
)
{
outputSignal
.
push_back
(
y
[
i
]
);
}
}
modules/transforms/resample_pqfraction/resample_pqfraction.json
0 → 100644
浏览文件 @
75d5536f
{
"resample_pqfraction"
:{
"name"
:
"resamplepq"
,
"parameters"
:{
"sptype"
:{
"type"
:
"enum"
,
"tooltip"
:
"sample point format"
,
"default"
:
0
,
"range"
:{
"0"
:
"16 bit Intel"
,
"1"
:
"16 bit Moto"
,
"2"
:
"int8"
,
"3"
:
"uint8"
}
},
"type"
:{
"type"
:
"int"
,
"tooltip"
:
"type"
,
"default"
:
"1"
,
"range"
:
"0:real,1:complex"
},
"np"
:{
"type"
:
"int"
,
"tooltip"
:
"new rate"
,
"default"
:
"1"
,
"range"
:
"N"
},
"nq"
:{
"type"
:
"int"
,
"tooltip"
:
"old rate"
,
"default"
:
"1"
,
"range"
:
"N"
}
},
"input_subjects"
:
{
"in"
:{
"type"
:
"byte"
,
"tooltip"
:
"Input"
},
"in_time"
:{
"type"
:
"timestamp"
,
"tooltip"
:
"Input timestamp"
}
},
"output_subjects"
:{
"out"
:{
"type"
:
"vector"
,
"tooltip"
:
"Output"
},
"out_time"
:{
"type"
:
"timestamp"
,
"tooltip"
:
"Out timestamp"
}
}
}
}
modules/transforms/resample_pqfraction/resample_pqfraction.pro
0 → 100644
浏览文件 @
75d5536f
TEMPLATE
=
app
QT
-=
gui
CONFIG
+=
c
++
11
console
CONFIG
-=
app_bundle
INCLUDEPATH
+=
..
/../../
tb_interface
DESTDIR
=
$$
OUT_PWD
/../../../
bin
/
modules
SOURCES
+=
\
main
.
cpp
HEADERS
+=
\
upfirdn
.
h
resample
.
h
RESOURCES
+=
resample_pqfraction
.
qrc
modules/transforms/resample_pqfraction/resample_pqfraction.qrc
0 → 100644
浏览文件 @
75d5536f
<RCC>
<qresource prefix="/">
<file>resample_pqfraction.json</file>
</qresource>
</RCC>
modules/transforms/resample_pqfraction/upfirdn.h
0 → 100644
浏览文件 @
75d5536f
/*
Copyright (c) 2009, Motorola, Inc
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Motorola nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
using
namespace
std
;
#include <stdexcept>
#include <complex>
#include <vector>
template
<
class
S1
,
class
S2
,
class
C
>
class
Resampler
{
public:
typedef
S1
inputType
;
typedef
S2
outputType
;
typedef
C
coefType
;
Resampler
(
int
upRate
,
int
downRate
,
C
*
coefs
,
int
coefCount
);
virtual
~
Resampler
();
int
apply
(
S1
*
in
,
int
inCount
,
S2
*
out
,
int
outCount
);
int
neededOutCount
(
int
inCount
);
int
coefsPerPhase
()
{
return
_coefsPerPhase
;
}
private:
int
_upRate
;
int
_downRate
;
coefType
*
_transposedCoefs
;
inputType
*
_state
;
inputType
*
_stateEnd
;
int
_paddedCoefCount
;
// ceil(len(coefs)/upRate)*upRate
int
_coefsPerPhase
;
// _paddedCoefCount / upRate
int
_t
;
// "time" (modulo upRate)
int
_xOffset
;
};
#include <iostream>
#include <cmath>
/*
using std::cout;
using std::endl;
using std::fill;
using std::copy;
*/
using
std
::
invalid_argument
;
template
<
class
S1
,
class
S2
,
class
C
>
Resampler
<
S1
,
S2
,
C
>::
Resampler
(
int
upRate
,
int
downRate
,
C
*
coefs
,
int
coefCount
)
:
_upRate
(
upRate
),
_downRate
(
downRate
),
_t
(
0
),
_xOffset
(
0
)
/*
The coefficients are copied into local storage in a transposed, flipped
arrangement. For example, suppose upRate is 3, and the input number
of coefficients coefCount = 10, represented as h[0], ..., h[9].
Then the internal buffer will look like this:
h[9], h[6], h[3], h[0], // flipped phase 0 coefs
0, h[7], h[4], h[1], // flipped phase 1 coefs (zero-padded)
0, h[8], h[5], h[2], // flipped phase 2 coefs (zero-padded)
*/
{
_paddedCoefCount
=
coefCount
;
while
(
_paddedCoefCount
%
_upRate
)
{
_paddedCoefCount
++
;
}
_coefsPerPhase
=
_paddedCoefCount
/
_upRate
;
_transposedCoefs
=
new
coefType
[
_paddedCoefCount
];
fill
(
_transposedCoefs
,
_transposedCoefs
+
_paddedCoefCount
,
0.
);
_state
=
new
inputType
[
_coefsPerPhase
-
1
];
_stateEnd
=
_state
+
_coefsPerPhase
-
1
;
fill
(
_state
,
_stateEnd
,
0.
);
/* This both transposes, and "flips" each phase, while
* copying the defined coefficients into local storage.
* There is probably a faster way to do this
*/
for
(
int
i
=
0
;
i
<
_upRate
;
++
i
)
{
for
(
int
j
=
0
;
j
<
_coefsPerPhase
;
++
j
)
{
if
(
j
*
_upRate
+
i
<
coefCount
)
_transposedCoefs
[(
_coefsPerPhase
-
1
-
j
)
+
i
*
_coefsPerPhase
]
=
coefs
[
j
*
_upRate
+
i
];
}
}
}
template
<
class
S1
,
class
S2
,
class
C
>
Resampler
<
S1
,
S2
,
C
>::~
Resampler
()
{
delete
[]
_transposedCoefs
;
delete
[]
_state
;
}
template
<
class
S1
,
class
S2
,
class
C
>
int
Resampler
<
S1
,
S2
,
C
>::
neededOutCount
(
int
inCount
)
/* compute how many outputs will be generated for inCount inputs */
{
int
np
=
inCount
*
_upRate
;
int
need
=
np
/
_downRate
;
if
((
_t
+
_upRate
*
_xOffset
)
<
(
np
%
_downRate
))
need
++
;
return
need
;
}
template
<
class
S1
,
class
S2
,
class
C
>
int
Resampler
<
S1
,
S2
,
C
>::
apply
(
S1
*
in
,
int
inCount
,
S2
*
out
,
int
outCount
)
{
if
(
outCount
<
neededOutCount
(
inCount
))
throw
invalid_argument
(
"Not enough output samples"
);
// x points to the latest processed input sample
inputType
*
x
=
in
+
_xOffset
;
outputType
*
y
=
out
;
inputType
*
end
=
in
+
inCount
;
while
(
x
<
end
)
{
outputType
acc
=
0.
;
coefType
*
h
=
_transposedCoefs
+
_t
*
_coefsPerPhase
;
inputType
*
xPtr
=
x
-
_coefsPerPhase
+
1
;
int
offset
=
in
-
xPtr
;
if
(
offset
>
0
)
{
// need to draw from the _state buffer
inputType
*
statePtr
=
_stateEnd
-
offset
;
while
(
statePtr
<
_stateEnd
)
{
acc
+=
*
statePtr
++
*
*
h
++
;
}
xPtr
+=
offset
;
}
while
(
xPtr
<=
x
)
{
acc
+=
*
xPtr
++
*
*
h
++
;
}
*
y
++
=
acc
;
_t
+=
_downRate
;
int
advanceAmount
=
_t
/
_upRate
;
x
+=
advanceAmount
;
// which phase of the filter to use
_t
%=
_upRate
;
}
_xOffset
=
x
-
end
;
// manage _state buffer
// find number of samples retained in buffer:
int
retain
=
(
_coefsPerPhase
-
1
)
-
inCount
;
if
(
retain
>
0
)
{
// for inCount smaller than state buffer, copy end of buffer
// to beginning:
copy
(
_stateEnd
-
retain
,
_stateEnd
,
_state
);
// Then, copy the entire (short) input to end of buffer
copy
(
in
,
end
,
_stateEnd
-
inCount
);
}
else
{
// just copy last input samples into state buffer
copy
(
end
-
(
_coefsPerPhase
-
1
),
end
,
_state
);
}
// number of samples computed
return
y
-
out
;
}
template
<
class
S1
,
class
S2
,
class
C
>
void
upfirdn
(
int
upRate
,
int
downRate
,
S1
*
input
,
int
inLength
,
C
*
filter
,
int
filterLength
,
vector
<
S2
>
&
results
)
/*
This template function provides a one-shot resampling. Extra samples
are padded to the end of the input in order to capture all of the non-zero
output samples.
The output is in the "results" vector which is modified by the function.
Note, I considered returning a vector instead of taking one on input, but
then the C++ compiler has trouble with implicit template instantiation
(e.g. have to say upfirdn<float, float, float> every time - this
way we can let the compiler infer the template types).
Thanks to Lewis Anderson (lkanders@ucsd.edu) at UCSD for
the original version of this function.
*/
{
// Create the Resampler
Resampler
<
S1
,
S2
,
C
>
theResampler
(
upRate
,
downRate
,
filter
,
filterLength
);
// pad input by length of one polyphase of filter to flush all values out
int
padding
=
theResampler
.
coefsPerPhase
()
-
1
;
S1
*
inputPadded
=
new
S1
[
inLength
+
padding
];
for
(
int
i
=
0
;
i
<
inLength
+
padding
;
i
++
)
{
if
(
i
<
inLength
)
inputPadded
[
i
]
=
input
[
i
];
else
inputPadded
[
i
]
=
0
;
}
// calc size of output
int
resultsCount
=
theResampler
.
neededOutCount
(
inLength
+
padding
);
results
.
resize
(
resultsCount
);
// run filtering
int
numSamplesComputed
=
theResampler
.
apply
(
inputPadded
,
inLength
+
padding
,
&
results
[
0
],
resultsCount
);
delete
[]
inputPadded
;
}
template
<
class
S1
,
class
S2
,
class
C
>
void
upfirdn
(
int
upRate
,
int
downRate
,
vector
<
S1
>
&
input
,
vector
<
C
>
&
filter
,
vector
<
S2
>
&
results
)
/*
This template function provides a one-shot resampling.
The output is in the "results" vector which is modified by the function.
In this version, the input and filter are vectors as opposed to
pointer/count pairs.
*/
{
upfirdn
<
S1
,
S2
,
C
>
(
upRate
,
downRate
,
&
input
[
0
],
input
.
size
(),
&
filter
[
0
],
filter
.
size
(),
results
);
}
modules/uhd/uhd_usrp_continous/uhd_io_continous.cpp
浏览文件 @
75d5536f
...
@@ -56,7 +56,7 @@ int do_iio(const cmdlineParser & args)
...
@@ -56,7 +56,7 @@ int do_iio(const cmdlineParser & args)
std
::
vector
<
double
>
rx_bw
=
args
.
toDoubleArray
(
"rx_bw"
);
std
::
vector
<
double
>
rx_bw
=
args
.
toDoubleArray
(
"rx_bw"
);
adjuestUnit
<
double
>
(
rx_channel_count
,
rx_bw
,
0
,
1e6
);
adjuestUnit
<
double
>
(
rx_channel_count
,
rx_bw
,
0
,
1e6
);
//RX Antenna
//RX Antenna
std
::
vector
<
std
::
string
>
rx_atn
=
args
.
toStringArray
(
"rx_a
ntenna
"
);
std
::
vector
<
std
::
string
>
rx_atn
=
args
.
toStringArray
(
"rx_a
tn
"
);
adjustString
(
rx_channel_count
,
rx_atn
,
"RX2"
);
adjustString
(
rx_channel_count
,
rx_atn
,
"RX2"
);
//RX switch
//RX switch
bool
rx_on
=
args
.
toInt
(
"rx_on"
,
0
)
?
true
:
false
;
bool
rx_on
=
args
.
toInt
(
"rx_on"
,
0
)
?
true
:
false
;
...
@@ -81,7 +81,7 @@ int do_iio(const cmdlineParser & args)
...
@@ -81,7 +81,7 @@ int do_iio(const cmdlineParser & args)
std
::
vector
<
double
>
tx_bw
=
args
.
toDoubleArray
(
"tx_bw"
);
std
::
vector
<
double
>
tx_bw
=
args
.
toDoubleArray
(
"tx_bw"
);
adjuestUnit
<
double
>
(
tx_channel_count
,
tx_bw
,
0
,
1e6
);
adjuestUnit
<
double
>
(
tx_channel_count
,
tx_bw
,
0
,
1e6
);
//TX Antenna
//TX Antenna
std
::
vector
<
std
::
string
>
tx_atn
=
args
.
toStringArray
(
"tx_a
ntenna
"
);
std
::
vector
<
std
::
string
>
tx_atn
=
args
.
toStringArray
(
"tx_a
tn
"
);
adjustString
(
rx_channel_count
,
tx_atn
,
"TX/RX"
);
adjustString
(
rx_channel_count
,
tx_atn
,
"TX/RX"
);
//TX switch
//TX switch
bool
tx_on
=
args
.
toInt
(
"tx_on"
,
0
)
?
true
:
false
;
bool
tx_on
=
args
.
toInt
(
"tx_on"
,
0
)
?
true
:
false
;
...
...
modules/uhd/uhd_usrp_io/uhd_io.cpp
浏览文件 @
75d5536f
...
@@ -98,7 +98,7 @@ int do_iio(const cmdlineParser & args)
...
@@ -98,7 +98,7 @@ int do_iio(const cmdlineParser & args)
std
::
vector
<
double
>
rx_bw
=
args
.
toDoubleArray
(
"rx_bw"
);
std
::
vector
<
double
>
rx_bw
=
args
.
toDoubleArray
(
"rx_bw"
);
adjuestUnit
<
double
>
(
rx_channel_count
,
rx_bw
,
0
,
1e6
);
adjuestUnit
<
double
>
(
rx_channel_count
,
rx_bw
,
0
,
1e6
);
//RX Antenna
//RX Antenna
std
::
vector
<
std
::
string
>
rx_atn
=
args
.
toStringArray
(
"rx_a
ntenna
"
);
std
::
vector
<
std
::
string
>
rx_atn
=
args
.
toStringArray
(
"rx_a
tn
"
);
adjustString
(
rx_channel_count
,
rx_atn
,
"RX2"
);
adjustString
(
rx_channel_count
,
rx_atn
,
"RX2"
);
//RX switch
//RX switch
...
@@ -121,7 +121,7 @@ int do_iio(const cmdlineParser & args)
...
@@ -121,7 +121,7 @@ int do_iio(const cmdlineParser & args)
std
::
vector
<
double
>
tx_bw
=
args
.
toDoubleArray
(
"tx_bw"
);
std
::
vector
<
double
>
tx_bw
=
args
.
toDoubleArray
(
"tx_bw"
);
adjuestUnit
<
double
>
(
tx_channel_count
,
tx_bw
,
0
,
1e6
);
adjuestUnit
<
double
>
(
tx_channel_count
,
tx_bw
,
0
,
1e6
);
//TX Antenna
//TX Antenna
std
::
vector
<
std
::
string
>
tx_atn
=
args
.
toStringArray
(
"tx_a
ntenna
"
);
std
::
vector
<
std
::
string
>
tx_atn
=
args
.
toStringArray
(
"tx_a
tn
"
);
adjustString
(
rx_channel_count
,
tx_atn
,
"TX/RX"
);
adjustString
(
rx_channel_count
,
tx_atn
,
"TX/RX"
);
//TX switch
//TX switch
bool
tx_on
=
args
.
toInt
(
"tx_on"
,
0
)
?
true
:
false
;
bool
tx_on
=
args
.
toInt
(
"tx_on"
,
0
)
?
true
:
false
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录