|
|
@ -45,7 +45,12 @@ static void *sound_read_thread_func(void *v); |
|
|
|
static void gpio_set_value(int value) { write(m_gpiofd, value ? "1\n" : "0\n", 2); } |
|
|
|
static void readvoice(); |
|
|
|
|
|
|
|
static int32_t *multiplierX2(int32_t *voice, int32_t size, int32_t *outsize) { |
|
|
|
typedef struct { |
|
|
|
int32_t *voice; |
|
|
|
int32_t size; |
|
|
|
} audio_t; |
|
|
|
|
|
|
|
static audio_t multiplierX2(int32_t *voice, int32_t size) { |
|
|
|
static int32_t voicebuf[MAX_ONE_FRAME_VOICE_SIZE * 2]; // 50ms |
|
|
|
if (size > MAX_ONE_FRAME_VOICE_SIZE) { |
|
|
|
size = MAX_ONE_FRAME_VOICE_SIZE; |
|
|
@ -57,37 +62,82 @@ static int32_t *multiplierX2(int32_t *voice, int32_t size, int32_t *outsize) { |
|
|
|
voicebuf[i * 2 + 1] = (voice[i] + voice[i + 1]) / 2; |
|
|
|
} |
|
|
|
} |
|
|
|
*outsize = size * 2; |
|
|
|
return voicebuf; |
|
|
|
audio_t ret; |
|
|
|
ret.size = size * 2; |
|
|
|
ret.voice = voicebuf; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
static void filterVoice(int32_t *voice, int32_t size) { |
|
|
|
/** |
|
|
|
* @brief 简单的过滤器,如果当前点大于上一个点和下一个点的平均值的1.5倍,则将当前点设置为平均值 |
|
|
|
*/ |
|
|
|
static int32_t lastvoice = 0; |
|
|
|
lastvoice = voice[size - 1]; |
|
|
|
|
|
|
|
{ // |
|
|
|
int32_t avg = (lastvoice + voice[1]) / 2; |
|
|
|
if (abs(voice[0]) > abs(avg * 1.5)) { |
|
|
|
voice[0] = avg; |
|
|
|
} |
|
|
|
static audio_t multiplierX2_2(int32_t *voice, int32_t size) { |
|
|
|
static int32_t voicebuf[MAX_ONE_FRAME_VOICE_SIZE * 4]; // 50ms |
|
|
|
if (size > MAX_ONE_FRAME_VOICE_SIZE) { |
|
|
|
size = MAX_ONE_FRAME_VOICE_SIZE; |
|
|
|
} |
|
|
|
|
|
|
|
for (size_t i = 1; i < size - 1; i++) { |
|
|
|
int32_t avg = (voice[i - 1] + voice[i + 1]) / 2; |
|
|
|
if (abs(voice[i]) > abs(avg * 1.5)) { |
|
|
|
voice[i] = avg; |
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
voicebuf[i * 2] = voice[i]; |
|
|
|
if (i + 1 < size) { |
|
|
|
voicebuf[i * 2 + 1] = (voice[i] + voice[i + 1]) / 2; |
|
|
|
} |
|
|
|
} |
|
|
|
audio_t ret; |
|
|
|
ret.size = size * 2; |
|
|
|
ret.voice = voicebuf; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
int32_t expectendvoice = voice[size - 2] + (voice[size - 2] - voice[size - 3]); |
|
|
|
if (abs(voice[size - 1]) > abs(expectendvoice * 1.5)) { |
|
|
|
voice[size - 1] = expectendvoice; |
|
|
|
static int32_t filter(int32_t input, int32_t v1, int32_t v2, int32_t v3, int32_t v4, int32_t v5, int32_t v6) { |
|
|
|
int32_t v[6]; |
|
|
|
v[0] = v1; |
|
|
|
v[1] = v2; |
|
|
|
v[2] = v3; |
|
|
|
v[3] = v4; |
|
|
|
v[4] = v5; |
|
|
|
v[5] = v6; |
|
|
|
|
|
|
|
// 对v进行排序 |
|
|
|
for (size_t i = 0; i < 6; i++) { |
|
|
|
for (size_t j = i + 1; j < 6; j++) { |
|
|
|
if (v[i] > v[j]) { |
|
|
|
int32_t tmp = v[i]; |
|
|
|
v[i] = v[j]; |
|
|
|
v[j] = tmp; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int expect = (v[2] + v[3]) / 2; |
|
|
|
if (abs(input) > abs(expect * 2) || abs(input) < abs(expect / 2)) { |
|
|
|
return expect; |
|
|
|
} else { |
|
|
|
return input; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static bool filterVoice(int32_t *voice, int32_t size) { |
|
|
|
#if 0 |
|
|
|
static int32_t vbuf[MAX_ONE_FRAME_VOICE_SIZE * 3]; // 50ms |
|
|
|
static int32_t vbufnum = 0; |
|
|
|
vbufnum++; |
|
|
|
|
|
|
|
memmove(vbuf, vbuf + size, 2 * size * sizeof(int32_t)); |
|
|
|
memcpy(vbuf + 2 * size, voice, size * sizeof(int32_t)); |
|
|
|
|
|
|
|
if (vbufnum < 3) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
#endif |
|
|
|
static int32_t vbuf[MAX_ONE_FRAME_VOICE_SIZE]; // 50ms |
|
|
|
memcpy(vbuf, voice, size * sizeof(int32_t)); |
|
|
|
|
|
|
|
int32_t *cachebegin = vbuf; |
|
|
|
|
|
|
|
for (int32_t i = 3; i < size - 3; i++) { |
|
|
|
voice[i] = filter(voice[i], *(cachebegin + i - 1), *(cachebegin + i - 2), *(cachebegin + i - 3), *(cachebegin + i + 1), *(cachebegin + i + 2), |
|
|
|
*(cachebegin + i + 3)); |
|
|
|
// voice[i] = cachebegin[i]; |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
error_code_t spisound_init(const char *deviceName, int csgpionameId, spisound_cb_t callback) { |
|
|
@ -167,6 +217,7 @@ static void readvoice() { |
|
|
|
gpio_set_value(0); |
|
|
|
// usleep(1500); // CS信号触发后,给单片机足够的时间准备音频数据 |
|
|
|
int ret = read(m_fd, &rxdatabytesize, 4); |
|
|
|
// printf("%d\n",rxdatabytesize); |
|
|
|
// printf("read rxdatabytesize:%d\n", rxdatabytesize); |
|
|
|
if (rxdatabytesize <= 0) { |
|
|
|
gpio_set_value(1); |
|
|
@ -181,11 +232,12 @@ static void readvoice() { |
|
|
|
ret = read(m_fd, voicebuf, rxdatabytesize); |
|
|
|
gpio_set_value(1); |
|
|
|
|
|
|
|
{ |
|
|
|
int32_t voiceframesize = 0; |
|
|
|
filterVoice(voicebuf, rxdatabytesize / 4); |
|
|
|
int32_t *voicereport = multiplierX2(voicebuf, rxdatabytesize / 4, &voiceframesize); |
|
|
|
if (m_callback) m_callback(voicereport, voiceframesize); |
|
|
|
int32_t voiceframesize = 0; |
|
|
|
bool ready = filterVoice(voicebuf, rxdatabytesize / 4); |
|
|
|
if (ready) { |
|
|
|
audio_t v1 = multiplierX2(voicebuf, rxdatabytesize / 4); |
|
|
|
audio_t v2 = multiplierX2_2(v1.voice, v1.size); |
|
|
|
if (m_callback) m_callback(v2.voice, v2.size); |
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|