【问题标题】:Converting uint8_t buffer to complex float buffer in C++在 C++ 中将 uint8_t 缓冲区转换为复杂的浮点缓冲区
【发布时间】:2014-12-28 07:35:30
【问题描述】:

我正在从要解调的软件定义无线电读取 IQ 数据缓冲区。我收到的数据是 8 位无符号整数的缓冲区。我需要将其转换为缓冲区以输入复数浮点数以解调信号(我计划使用 Liquid DSP 库)。我在转换缓冲区时遇到了困难。

在 GNURadio 中,我已经制定了我的逻辑并将我的代码输出写入一个二进制文件,然后我可以将其用作测试的输入源。到目前为止,唯一可行的是将 uint8_t 缓冲区写入文件,对数据的其他操作会破坏逻辑。

这是我尝试过的 C++ 代码的 sn-p:

uint8_t buffer[buffersize];

uint8_t I;
uint8_t Q;

float Ifloat;
float Qfloat;

complex<float> complexsample;

ofstream myfile;
myfile.open("example.bin", ios::out | ios::app | ios::binary);

for (int x = 0; x < (buffersize/2); x++) {

    memcpy(&I, buffer + (2 * x), 1);
    memcpy(&Q, buffer + (1 + (2 * x)), 1);
    //writing I and Q above to a binary file works
        //myfile.write((char*) &I, sizeof(I));
        //myfile.write((char*) &Q, sizeof(Q));

    Ifloat = (float) I;
    Qfloat = (float) Q;
    //when I write Ifloat and Qfloat to a binary file then pass the 
    //file as an input source into the Add Const block things stop working
        //myfile.write((char*) &IIfloat, sizeof(Ifloat));
        //myfile.write((char*) &Qfloat, sizeof(Qfloat));


    Ifloat -= 127.0;
    Qfloat -= 127.0;
    //what I would do to turn the turn the unsigned value into a signed value
        //myfile.write((char*) &IIfloat, sizeof(Ifloat));
        //myfile.write((char*) &Qfloat, sizeof(Qfloat));

    complexsample.real(Ifloat);
    complexsample.imag(Qfloat);
    //what I would do to turn the I and Q floats into a single complex sample
        //myfile.write((char*) &complexsample, sizeof(complexsample));
}

【问题讨论】:

  • 你确定这段代码是你实际写的吗?因为如果I 的类型为uint8_t 而不是uint8_t [4]uint8_t *,我认为memcpy(I, buffer + (2 * x), 1); 没有多大意义。此外,通常浮点数是 4 个字节,而不是您在代码中不同程度假设的 2 个字节或 1 个字节。
  • 至少应该是memcpy(&amp;I, buffer + (2 * x), 1); 或简单的I = buffer[2 * x]
  • 我的代码中实际上有 memcpy(&I, buffer + (2 * x), 1),当我简化它以进行发布时,这是我的帖子中的错字。在我正在运行的代码中,我从一个 tcp 套接字接收,所以我只是为了简化而删除了该部分。
  • 我可能误解了,所以你实际上有 uint8_t 0-255 的值,你真的只是希望它们作为浮点数?
  • @jprince14 Liquid-dsp 或 gnuradio 或您插入的任何东西所期望的字节序是什么?

标签: c++ signals signal-processing gnuradio


【解决方案1】:

DrPaulBrewer 编写了一个简单的程序来进行我正在寻找的精确转换。他的 GitHub 链接是https://gist.github.com/DrPaulBrewer/917f990cc0a51f7febb5

他的源码是:

void main(int argc, char *argv[])
{
int byte1, byte2; // int -- not unsigned char -- see fgetc man page
float _Complex fc;
const size_t fc_size = sizeof(fc);
FILE *infile,*outfile;
const float scale = 1.0/128.0;
const char *infilename = argv[1];
const char *outfilename = argv[2];
if (argc<3){
printf("usage: rtlsdr-to-gqrx infile outfile\n");
exit(1);
}
// printf("in= %s out= %s \n", infilename, outfilename);
infile=fopen(infilename,"rb");
outfile=fopen(outfilename,"wb");
if ((infile==NULL) || (outfile==NULL)){
printf("Error opening files\n");
exit(1);
}
while ((byte1=fgetc(infile)) != EOF){
if ((byte2=fgetc(infile)) == EOF){
exit(0);
}
fc = scale*(byte1-127) + I*scale*(byte2-127);
fwrite(&fc,fc_size,1,outfile);
}
}

【讨论】:

  • 看起来字节顺序转换毕竟不是必需的,可能问题出在您的输入或复杂部分和虚部的写入顺序中
  • 看起来你的代码中缺少的只是除以 128.0
  • 我的代码在 C 和 C++99 中工作,但是当我使用 C++11 时出现错误 unable to find numeric literal operator ‘operator"" iF'。我想用来将复数传递到液体 DSP 库中,它需要输入浮点复数类型。或者有没有办法将 C++11 复数转换为 C 复数?我目前正在使用带有memcpy(&amp;c_complex,&amp;complexsample,sizeof(complexsample)) 的原始代码版本将C++ 复数转换为C 复数。这可行,但有没有更优雅的方式来进行这种转换或避免需要转换?
  • @BenVoigt 我尝试删除除以 128 的除法,代码仍然有效。我很困惑为什么原始代码不起作用。
猜你喜欢
  • 2021-05-11
  • 2021-01-14
  • 1970-01-01
  • 2023-03-02
  • 2022-08-05
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多