📄 g711_decode.sc
字号:
// g711_decode.sc// G.711 decoder StreamC demo program// N.B. system headers must precede "spi_common.h" for now...#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include "spi_common.h"// "RapiDev User's Guide" gives a tutorial introduction to this G.711 demo program.// This program is for --target host and --target tcshost only;// g711.sc is an alternative version for --target device.#if defined(SPI_TARGET_DEVICE)#error g711_decode.sc is for --target host and --target tcshost only.#endif // defined(SPI_TARGET_DEVICE)#define TEST_ITEMS 256 // input items in test// Input, output, reference filenames.#define INFILE "in.bin"#define OUTFILE "out.bin"#define REFFILE "ref.bin" // Data buffers.char inbuf[TEST_ITEMS]; // G.711 input (bytes)int outbuf[TEST_ITEMS]; // PCM output (words)int refbuf[TEST_ITEMS]; // PCM reference// Open a file, die on failure.FILE *xopen(char *name, char *mode){ FILE *fp; if ((fp = fopen(name, mode)) == NULL){ fprintf(stderr,"%s: open failed\n", name); exit(EXIT_FAILURE); } return fp;}// Read a file, die on failure.voidxread(char *name, char *mode, void *buf, int size, int count){ FILE *fp; fp = xopen(name, mode); if (fread(buf, size, count, fp) != count){ fprintf(stderr,"%s: read failed\n", name); exit(EXIT_FAILURE); } fclose(fp);}// Decode G.711 A-law to PCM.// Process one vec uint32x1 of input to one vec uint32x1 of output.inline kernel vec uint32x1 g711_decode( vec uint32x1 data(in) ){ vec int32x1 exponent; vec uint32x1 i; vec uint32x1 mantissa; i = (data ^ 0x55) & 0x7F; // re-toggle even bits, remove sign bit exponent = i >> 4; // extract exponent mantissa = i & 0xF; // extract mantissa mantissa = (exponent > 0) ? mantissa | 0x10 : mantissa; // restore hidden bit to mantissa mantissa = mantissa << 4 | 0x08u; // left justify, // add 1/2 quantization stepsize // Normalize mantissa if log encoding (not linear segment). mantissa = (exponent > 1) ? mantissa << exponent - 1 : mantissa; // Negate if sign bit was NOT set in input. mantissa = (data < 0x80u) ? -mantissa : mantissa; return mantissa << 16;}// The G711 decoding kernel.kernel void g711_decode_stream( stream int8x4 instream(cond_in), stream int32x1 outstream(seq_out), int32x1 count(in) ){ vec uint32x1 component; // source component (byte number) vec uint32x1 control; // control value for scatter vec uint32x1 data; // scattered input word vec int32x1 flag; // conditional input flag vec int32x1 lane; // source lane vec uint8x4 pdata; // packed input record uint8x4 dummy = 0p4; // unused scalar dummy arg for spi_vperm8 component = spi_laneid() & 0x03; // source component (0, 1, 2, 3, 0, 1, 2, 3, ...) lane = spi_laneid() >> 2; // source lane (0, 0, 0, 0, 1, 1, 1, 1, ...) control = (lane << 2) | component; // construct spi_vperm8() control arg flag = spi_laneid() < (SPI_LANES >> 2); // true in lanes 0, 1, 2, 3 while (count > 0) { spi_cond_read(instream, pdata, flag); // read packed input record in lanes 0, 1, 2, 3 pdata = spi_vperm8((vec uint8x4)control, pdata, dummy); // scatter packed byte data data = (vec uint32x1)pdata & 0xFF; // zero-extend byte data to word spi_write(outstream, g711_decode(data)); // invoke inline kernel to decode count = count - 1; }}intdspmain(void){ FILE *fp; int i; stream int8x4 instream(TEST_ITEMS / 4); // input stream (packed bytes) stream int32x1 outstream(TEST_ITEMS); // output stream (words) // Read input file. xread(INFILE, "rb", inbuf, sizeof(inbuf[0]), TEST_ITEMS); // Input stream length should be multiple of number of lanes, // otherwise it will be padded when passed to a kernel. if ((TEST_ITEMS % SPI_LANES) != 0){ fprintf(stderr,"TEST_ITEMS (%d) is not multiple of lane count (%d)\n", TEST_ITEMS, SPI_LANES); exit(EXIT_FAILURE); } // Load input stream data. spi_flush_entire_data_cache(); // flush cached memory data before spi_load spi_load(instream, inbuf, 0, TEST_ITEMS / 4); // Invoke kernel to decode. g711_decode_stream(instream, outstream, TEST_ITEMS / SPI_LANES); // Check output stream length. if (spi_count(outstream) != TEST_ITEMS){ fprintf(stderr,"unexpected output stream length %d\n", spi_count(outstream)); exit(EXIT_FAILURE); } // Store output stream data. spi_store(outstream, outbuf, 0, TEST_ITEMS); spi_barrier(); // to assure spi_store completion // Dump output data. fp = xopen(OUTFILE, "wb"); if (fwrite(outbuf, sizeof(outbuf[0]), TEST_ITEMS, fp) != TEST_ITEMS){ fprintf(stderr,"%s: write failed\n", OUTFILE); exit(EXIT_FAILURE); } fclose(fp); // Read reference file. xread(REFFILE, "rb", refbuf, sizeof(refbuf[0]), TEST_ITEMS); // Compare result to reference result. for (i = 0; i < TEST_ITEMS; i++) { if (outbuf[i] != refbuf[i]){ fprintf(stderr,"result miscompares at word %d: expected 0x%X, got 0x%X\n", i, refbuf[i], outbuf[i]); exit(EXIT_FAILURE); } } // Done. printf("Success!\n"); return 0;}intmain(int argc, char *argv[]){ return dspmain();}// end of g711_decode.sc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -