// Transit a buffer of <size> complex16 numbers // ptr has to be 16 aligned and has to have space for x8 complex16 numbers, due to efficien packing to complex8 void writeSora(BlinkParams *params, complex16 *ptr, ULONG size) { HRESULT hr; ULONG TxID; ULONG dbg=0; if (size*2 > params->radioParams.TXBufferSize) { fprintf (stderr, "Error: Sora Tx buffer too small (%ld needed)!\n", 2*size ); exit(1); } // Saturated packing need 16-bit aligned pointers since it uses SSE if ((ULONG)ptr & 0xF > 0) { fprintf (stderr, "Error: Tx ptr has to be 16 aligned!\n"); exit(1); } // Saturated pack from complex16 (default Blink TX type) to complex8 vcs *vPtr = (vcs*)ptr; unsigned int index = 0; for(int i=0; i<size/4; i+=2) { vcs s1, s2; s1 = vPtr[i]; s2 = vPtr[i+1]; vcb b = (vcb)saturated_pack((vs&)s1, (vs&)s2); char *dst = (char *) params->TXBuffer; memcpy((void*)(dst+index), (void*) (&b), sizeof(vcb)); index += sizeof(vcb); } // DEBUG: //hr = SoraURadioTransferEx(params->radioParams.radioId, params->TXBuffer, 2*size, &TxID); hr = SoraURadioTransferEx(params->radioParams.radioId, params->TXBuffer, 4*size, &TxID); if (!SUCCEEDED(hr)) { fprintf (stderr, "Error: Fail to transfer Sora Tx buffer!\n" ); exit(1); } hr = SoraURadioTx(params->radioParams.radioId, TxID); if (!SUCCEEDED(hr)) { fprintf (stderr, "Error: Fail to transmit Sora Tx buffer!\n" ); exit(1); } hr = SoraURadioTxFree(params->radioParams.radioId, TxID); }
// Currently only on Sora. To be ported to GCC/universal intrinsics //FINL void __ext_v_pack_complex16_complex8(struct complex8* output, int lenout, complex16* input, int lenin) { const int wlen = sizeof(vcs) / sizeof(complex16); int i; vcs *pinput = (vcs *) input; vcb *poutput = (vcb *) output; for (i = 0; i < lenin / wlen / 2; i++) { *poutput = (vcb)saturated_pack(*pinput, *(pinput + 1)); poutput++; pinput += 2; } for (int j = i * 2 * wlen; j < lenin; j++) { output[j].re = input[j].re; output[j].im = input[j].im; } }