📄 g711.sc
字号:
// g711.sc// G.711 decoder StreamC demo program// This version does not use file i/o.#include "spi_common.h"#define TEST_ITEMS 256 // input items in test// Data buffers.int refbuf[TEST_ITEMS] = { // PCM reference 0xEA800000, 0xEB800000, 0xE8800000, 0xE9800000, 0xEE800000, 0xEF800000, 0xEC800000, 0xED800000, 0xE2800000, 0xE3800000, 0xE0800000, 0xE1800000, 0xE6800000, 0xE7800000, 0xE4800000, 0xE5800000, 0xF5400000, 0xF5C00000, 0xF4400000, 0xF4C00000, 0xF7400000, 0xF7C00000, 0xF6400000, 0xF6C00000, 0xF1400000, 0xF1C00000, 0xF0400000, 0xF0C00000, 0xF3400000, 0xF3C00000, 0xF2400000, 0xF2C00000, 0xAA000000, 0xAE000000, 0xA2000000, 0xA6000000, 0xBA000000, 0xBE000000, 0xB2000000, 0xB6000000, 0x8A000000, 0x8E000000, 0x82000000, 0x86000000, 0x9A000000, 0x9E000000, 0x92000000, 0x96000000, 0xD5000000, 0xD7000000, 0xD1000000, 0xD3000000, 0xDD000000, 0xDF000000, 0xD9000000, 0xDB000000, 0xC5000000, 0xC7000000, 0xC1000000, 0xC3000000, 0xCD000000, 0xCF000000, 0xC9000000, 0xCB000000, 0xFEA80000, 0xFEB80000, 0xFE880000, 0xFE980000, 0xFEE80000, 0xFEF80000, 0xFEC80000, 0xFED80000, 0xFE280000, 0xFE380000, 0xFE080000, 0xFE180000, 0xFE680000, 0xFE780000, 0xFE480000, 0xFE580000, 0xFFA80000, 0xFFB80000, 0xFF880000, 0xFF980000, 0xFFE80000, 0xFFF80000, 0xFFC80000, 0xFFD80000, 0xFF280000, 0xFF380000, 0xFF080000, 0xFF180000, 0xFF680000, 0xFF780000, 0xFF480000, 0xFF580000, 0xFAA00000, 0xFAE00000, 0xFA200000, 0xFA600000, 0xFBA00000, 0xFBE00000, 0xFB200000, 0xFB600000, 0xF8A00000, 0xF8E00000, 0xF8200000, 0xF8600000, 0xF9A00000, 0xF9E00000, 0xF9200000, 0xF9600000, 0xFD500000, 0xFD700000, 0xFD100000, 0xFD300000, 0xFDD00000, 0xFDF00000, 0xFD900000, 0xFDB00000, 0xFC500000, 0xFC700000, 0xFC100000, 0xFC300000, 0xFCD00000, 0xFCF00000, 0xFC900000, 0xFCB00000, 0x15800000, 0x14800000, 0x17800000, 0x16800000, 0x11800000, 0x10800000, 0x13800000, 0x12800000, 0x1D800000, 0x1C800000, 0x1F800000, 0x1E800000, 0x19800000, 0x18800000, 0x1B800000, 0x1A800000, 0x0AC00000, 0x0A400000, 0x0BC00000, 0x0B400000, 0x08C00000, 0x08400000, 0x09C00000, 0x09400000, 0x0EC00000, 0x0E400000, 0x0FC00000, 0x0F400000, 0x0CC00000, 0x0C400000, 0x0DC00000, 0x0D400000, 0x56000000, 0x52000000, 0x5E000000, 0x5A000000, 0x46000000, 0x42000000, 0x4E000000, 0x4A000000, 0x76000000, 0x72000000, 0x7E000000, 0x7A000000, 0x66000000, 0x62000000, 0x6E000000, 0x6A000000, 0x2B000000, 0x29000000, 0x2F000000, 0x2D000000, 0x23000000, 0x21000000, 0x27000000, 0x25000000, 0x3B000000, 0x39000000, 0x3F000000, 0x3D000000, 0x33000000, 0x31000000, 0x37000000, 0x35000000, 0x01580000, 0x01480000, 0x01780000, 0x01680000, 0x01180000, 0x01080000, 0x01380000, 0x01280000, 0x01D80000, 0x01C80000, 0x01F80000, 0x01E80000, 0x01980000, 0x01880000, 0x01B80000, 0x01A80000, 0x00580000, 0x00480000, 0x00780000, 0x00680000, 0x00180000, 0x00080000, 0x00380000, 0x00280000, 0x00D80000, 0x00C80000, 0x00F80000, 0x00E80000, 0x00980000, 0x00880000, 0x00B80000, 0x00A80000, 0x05600000, 0x05200000, 0x05E00000, 0x05A00000, 0x04600000, 0x04200000, 0x04E00000, 0x04A00000, 0x07600000, 0x07200000, 0x07E00000, 0x07A00000, 0x06600000, 0x06200000, 0x06E00000, 0x06A00000, 0x02B00000, 0x02900000, 0x02F00000, 0x02D00000, 0x02300000, 0x02100000, 0x02700000, 0x02500000, 0x03B00000, 0x03900000, 0x03F00000, 0x03D00000, 0x03300000, 0x03100000, 0x03700000, 0x03500000,};// 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){ int i, nfailed; char *inbuf = NULL; int *outbuf = NULL; stream int8x4 instream(TEST_ITEMS / 4); // input stream (packed bytes) stream int32x1 outstream(TEST_ITEMS); // output stream (words) int status; // Allocate stream data buffers. if ((inbuf = (char *)spi_malloc(TEST_ITEMS)) == NULL || (outbuf = (int *)spi_malloc(TEST_ITEMS * sizeof(int))) == NULL) { spi_printf("buffer allocation failed\n"); status = 1; goto cleanup_label; } // 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) { spi_printf("TEST_ITEMS (%d) is not multiple of lane count (%d)\n", TEST_ITEMS, SPI_LANES); status = 1; goto cleanup_label; } // Initialize inbuf. for (i = 0; i < TEST_ITEMS; i++) inbuf[i] = i; // 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); // Store output stream data. spi_store(outstream, outbuf, 0, TEST_ITEMS); spi_barrier(); // wait for completion of spi_store // Check output stream length. if (spi_count(outstream) != TEST_ITEMS) { spi_printf("unexpected output stream length %d\n", spi_count(outstream)); status = 1; goto cleanup_label; } // Compare result to reference result. nfailed = 0; for (i = 0; i < TEST_ITEMS; i++) { if (outbuf[i] != refbuf[i]) { spi_printf("result miscompares at word %3d: expected 0x%08X, got 0x%08X\n", i, refbuf[i], outbuf[i]); ++nfailed; } } // Done. spi_printf(nfailed == 0 ? "Success!\n" : "Failure: %d tests failed\n", nfailed); status = nfailed;cleanup_label: if(inbuf) spi_free(inbuf); if(outbuf) spi_free(outbuf); return status;}#if !defined(SPI_TARGET_DEVICE)intmain(int argc, char *argv[]){ return dspmain();}#endif // !defined(SPI_TARGET_DEVICE)// end of g711.sc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -