Closed Mas313 closed 2 weeks ago
Integer formats always expect the maximum signed range, for 16 bit that would be 2^15-1 = 32767 to -2^15 = -32768. For float formats the range is normalized to +/-1.0.
The Pluto uses 12 bits but the transfer is 16 bits, so CU8 would leave some dynamic range unused, CS16 could be optimal and CF32 is wasting (USB) bandwith and needs to be converted anyway. See https://github.com/pothosware/SoapyPlutoSDR/blob/master/PlutoSDR_Streaming.cpp#L649
Note that complex float is just two channels (I/Q) interleaved floats. If you read from a stereo wave file that maps to the two stereo channels (left/right).
I did following but no luck, pluto not transmitting anything. I converted double to int16_t and changed soapy format to CS16. Any sugegstions please,
for (int i = 0; i < num_samples; i++) {
// Scale floating-point sample to signed 16-bit integer range (-32768 to 32767)
outI[i] = (int16_t)(I[i] * 32767);
outQ[i] = (int16_t)(Q[i] * 32767);
}
//values assigned to complex int16_t buffer like this
for (int a=0; a< num_samples; a++){
buf.real( outI[i] );
buf.imag( outQ[i] );
}
void *buffs[]={buf};
Thanks
Write your buffers to .cf32 and .cs16 files. Then open with https://triq.org/pdv/ to verify the data. E.g.
int fd = open("foo.cs16", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
perror("open()");
exit(1);
}
int r = write(fd, buf, num_samples * sizeof(int16_t) * 2);
printf("Wrote: %d bytes\n", r);
close(fd);
Thanks for the reply.
I have attached the results i cannot understood. First screen shot is of file containing I & Q int16_t samples interleaved in a buffer.
Second screenshot is of complex int16_t buffer with values stores as
buf.real( outI[i] );
buf.imag( outQ[i] );
I am producing zero IF signals so the SDR Fc should have no offset. I dont see any spectrum in any case.
both files look empty. somehow your data is not present in the original or much too quiet (too small numbers).
Try this to fill your complex float buffer. You'll get a pure tone at +10 kHz and a (-27 dB) noise background.
for (int i = 0; i < num_samples; i +=1) {
float ni = rand() / (float)RAND_MAX * 0.1f - 0.05f;
float nq = rand() / (float)RAND_MAX * 0.1f - 0.05f;
float ph = i / 3.0;
buf[i] = ni + cosf(ph) + nq + sinf(ph) * I;
}
I have implemented your code and stores file as
int main()
{
int num_samples=10000;
complex float buf[num_samples];
for (int i = 0; i < num_samples; i +=1) {
float ni = rand() / (float)RAND_MAX * 0.1f - 0.05f;
float nq = rand() / (float)RAND_MAX * 0.1f - 0.05f;
float ph = i / 3.0;
buf[i] = ni + cosf(ph) + nq + sinf(ph) * I;
}
int fd = open("Tone.cf32", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
perror("open()");
exit(1);
}
int r = write(fd, buf, num_samples * sizeof(float) * 2);
printf("Wrote: %d bytes\n", r);
close(fd);
return 0;
}
Got following
When i transmitted same data using following code i got multiple harmonics ( not 10 Khz offset to carrier) verified throgh SDR sharp on another PC. I used plutosdr using c as follows:
int delay=1000000;
double carrier_frequency=800025000;
double sampling_rate=2000000.0;
double tx_gain=65.0;
int main()
{
SoapySDRDevice *sdr = NULL;
SoapySDRKwargs args = {};
int num_samples=313;
complex float buf[num_samples];
for (int i = 0; i < num_samples; i +=1) {
float ni = rand() / (float)RAND_MAX * 0.1f - 0.05f;
float nq = rand() / (float)RAND_MAX * 0.1f - 0.05f;
float ph = i / 3.0;
buf[i] = ni + cosf(ph) + nq + sinf(ph) * I;
}
int fd = open("Tone.cf32", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
perror("open()");
exit(1);
}
int r = write(fd, buf, num_samples * sizeof(float) * 2);
printf("Wrote: %d bytes\n", r);
close(fd);
// Soapy Sending
SoapySDRKwargs_set(&args, "driver", "plutosdr");
//SoapySDRDevice *sdr = SoapySDRDevice_make(&args);
sdr = SoapySDRDevice_make(&args);
SoapySDRKwargs_clear(&args);
printf("After SoapySDRKwargs_clear(&args) \n");
if (sdr == NULL)
{
printf("Errorr SoapySDRDevice_make fail: %s\n", SoapySDRDevice_lastError());
return 1;
}
if (sdr == NULL) {
fprintf(stderr, "Failed to create SoapySDR device\n");
return 1;
}
// Set sample rate, center frequency, and gain
SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_TX, 0, sampling_rate);
SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_TX, 0, carrier_frequency, NULL);
SoapySDRDevice_setGain(sdr, SOAPY_SDR_TX, 0, tx_gain);
// Create TX stream
printf(" Before: SoapySDRDevice_setupStream for Tx \n");// float 32 bit SOAPY_SDR_F32
SoapySDRStream *txStream = SoapySDRDevice_setupStream(sdr,SOAPY_SDR_TX,SOAPY_SDR_CF32,NULL,0, NULL);
if (txStream == NULL)
{
printf("setupStream fail: %s\n", SoapySDRDevice_lastError());
SoapySDRDevice_unmake(sdr);
exit(0);
return EXIT_FAILURE;
}
printf(" After: SoapySDRDevice_setupStream \n");
int sres=SoapySDRDevice_activateStream(sdr, txStream, 0, 0, 0); //start streaming
printf(" After calling-------- SoapySDRDevice_activateStream Tx sres=%d \n",sres);
getchar();
int flags = 0;
long long timeNs = 0;
int loop=0;
while(loop++<10){
int numcount=num_samples; //num_samples*2; //j;
int count=0;
//while(numcount > 0){
// printf("bEFORE void *buffs[] = {buffp} \n");
const void *buffs[] = {buf}; // {buffp};
// printf("AFTER void *buffs[] = {buffp} \n");
if(sdr==NULL || txStream ==NULL ){
printf("NULL " );
exit(0);
}
printf("=====Writing with Buffer count=%d\n",numcount);
int ret=SoapySDRDevice_writeStream(sdr, txStream, buffs, numcount, &flags, timeNs, 1000000);
if (ret <= 0){
printf("writeStream Error ret %d\n",ret);
exit(0);
}
if (ret > 0){
printf("writeStream Ok ret %d\n",ret);
}
//}
printf("-------------Complete One buffer transmitted with count= %d\n",count);
usleep(delay);
}
return 0;
}
Looks like a good transmission! The harmonics would be from the maxed out amplitude, you can try to scale the cos and sin down with e.g. 0.9 *
This example shows that very likely your earlier input buffer did not contain good samples.
Hi I am having trouble transmitting with plutosdr with specified formats like CF32 and CS 16 . Although I was able to send some pulses using CU8 format but those were values like 127 -127 , more here https://github.com/pothosware/SoapyPlutoSDR/issues/63.
I have gausian filtered data that has been accumulated (integrated). Now trying to transmit the data results in no transmisssion, verified through 'SdrSharp'. I want to know what values the soapysdr library expects for pluto to be. When using complex float or 16 bit integer, What is the range of values the data should fit in?. Also I have seen example of narrow band fm transmitter where CF32 format is used and the samples values are stored in a variable and assigned to void buffer like this
Now transmission is done with writestream function. Here I assume that wave file already had scaled samples so no scaling was done and wave file transmitted successfully. But it seems strange that CF32 format was specified but samples were stored in float (not complex float) and it did transmit. Besides this the main question is what are the ranges the data should fit in for float and 16 bit integer samples. Thanks