Browse Source

update

master
zhaohe 2 years ago
parent
commit
1e1f6d8f41
  1. 2
      README.md
  2. 90
      demo/adc_capture/libiflytop_adc_capture.c
  3. 8
      demo/adc_capture/libiflytop_adc_capture.h
  4. 143
      demo/adc_capture/main.cpp

2
README.md

@ -24,5 +24,7 @@ ADC
修改用户
DC
如何远程登陆
```

90
demo/adc_capture/libiflytop_adc_capture.c

@ -13,7 +13,7 @@
#include <string.h> //for strerror()
#include <sys/ioctl.h>
#include <unistd.h>
static const char *m_deviceName = NULL;
// static const char *m_deviceName = NULL;
static sound_capture_callback_t m_callback = NULL;
static int m_fd = 0;
static int m_sys_error = 0;
@ -91,7 +91,7 @@ error_code_t sound_capturer_init(const char *deviceName, int csgpionameId, sound
IOCTL(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, speed, ksp_init_spi_error_set_mode_fail);
char cmd[256] = {0};
sprintf(cmd, "echo %d > /sys/class/gpio/export", m_cs_gpio_id);
sprintf(cmd, "echo %d 1> /sys/class/gpio/export 2>/dev/null", m_cs_gpio_id);
system(cmd);
sprintf(cmd, "echo out > /sys/class/gpio/gpio%d/direction", m_cs_gpio_id);
@ -134,32 +134,90 @@ int spi_read(unsigned char *rxbuf, int len) {
// gpio_set_value(1);
printf("read %d bytes\n", ret);
return ret;
}
#define MAX_ONE_FRAME_VOICE_SIZE 2000
static int32_t *multiplierX2(int32_t *voice, int32_t size, int32_t *outsize) {
static int32_t voicebuf[MAX_ONE_FRAME_VOICE_SIZE * 2]; // 50ms
if (size > MAX_ONE_FRAME_VOICE_SIZE) {
size = MAX_ONE_FRAME_VOICE_SIZE;
}
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;
}
}
*outsize = size * 2;
return voicebuf;
}
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;
}
}
void readvoice() {
static int32_t voicebuf[4800]; // 50ms
static int32_t voiceNum; //
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;
}
}
voiceNum = 0;
{
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 void readvoice() {
static int32_t voicebuf[MAX_ONE_FRAME_VOICE_SIZE]; // 50ms
static int32_t rxdatabytesize; //
rxdatabytesize = 0;
memset(voicebuf, 0, sizeof(voicebuf));
gpio_set_value(0);
usleep(20);
int ret = read(m_fd, &voiceNum, 4);
printf("read voiceNum:%d\n", voiceNum);
if (voiceNum <= 0) {
usleep(1500); // CS信号触发后
int ret = read(m_fd, &rxdatabytesize, 4);
// printf("read rxdatabytesize:%d\n", rxdatabytesize);
if (rxdatabytesize <= 0) {
gpio_set_value(1);
return;
}
if (voiceNum > 4800) {
printf("WARNING: voiceNum(%d) > voiceBufSize \n", voiceNum);
voiceNum = 4800;
if (rxdatabytesize > MAX_ONE_FRAME_VOICE_SIZE * 4) {
printf("WARNING: rxdatabytesize(%d) > voiceBufSize \n", rxdatabytesize);
gpio_set_value(1);
return;
}
ret = read(m_fd, voicebuf, voiceNum * 4);
ret = read(m_fd, voicebuf, rxdatabytesize);
gpio_set_value(1);
// for (size_t i = 0; i < rxdatabytesize/4; i++) {
// printf("%d \n", voicebuf[i]);
// }
{
int32_t voiceframesize = 0;
filterVoice(voicebuf, rxdatabytesize / 4);
int32_t *voicereport = multiplierX2(voicebuf, rxdatabytesize / 4, &voiceframesize);
if (m_callback) m_callback(voicereport, voiceframesize);
}
return;
}
@ -167,7 +225,7 @@ static void *sound_read_thread_func(void *v) {
while (true) {
// 500us
readvoice();
usleep(5000);
usleep(10000);
}
return NULL;
}

8
demo/adc_capture/libiflytop_adc_capture.h

@ -4,7 +4,13 @@
#ifdef cplusplus
extern "C" {
#endif
typedef void (*sound_capture_callback_t)(uint32_t* data, uint32_t len);
/**
* @brief
*
* 48K,24bit的采样精度的音频数据
*
*/
typedef void (*sound_capture_callback_t)(int32_t* data, uint32_t len);
typedef enum {
ksp_success,

143
demo/adc_capture/main.cpp

@ -10,13 +10,154 @@
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
extern "C" {
#include "libiflytop_adc_capture.h"
}
void sound_capture_callback(uint32_t* data, uint32_t len) {}
using namespace std;
class WAVHeader {
public:
/**
* @brief WAV
*
* WAV
* - "RIFF" 4 chunk_id
* - - 8 4 chunk_size
* - "WAVE" 4 format
* - "fmt " 4 subchunk1_id
* - 16 4 subchunk1_size
* - 1 PCM 2 audio_format
* - 1 2 2 num_channels
* - 44100 4 sample_rate
* - * * / 8 4 byte_rate
* - 2 16 2 2 block_align
* - 8162432 2 bits_per_sample
* - "data" 4 subchunk2_id
* - - 44 4 subchunk2_size
*/
struct WAVHeaderBinary {
char chunk_id[4]; // 固定为 "RIFF"
uint32_t chunk_size; // 文件总大小 - 8
char format[4]; // 固定为 "WAVE"
char subchunk1_id[4]; // 固定为 "fmt "
uint32_t subchunk1_size; // 固定为 16
uint16_t audio_format; // 编码格式,1 表示 PCM 编码
uint16_t num_channels; // 声道数,1 为单声道,2 为立体声
uint32_t sample_rate; // 采样率,如 44100
uint32_t byte_rate; // 数据传输速率,即采样率 * 声道数 * 位数 / 8
uint16_t block_align; // 数据块对齐,即每个采样点占用的字节数,如 2 表示 16 位,即 2 字节
uint16_t bits_per_sample; // 位数,如 8、16、24、32
char subchunk2_id[4]; // 固定为 "data"
uint32_t subchunk2_size; // 数据长度,即文件总大小 - 44
};
WAVHeaderBinary header;
public:
WAVHeader() {}
void initialize(uint32_t sample_rate, uint16_t bits_per_sample, uint16_t num_channels, uint32_t wavbinsize) {
// 填充 RIFF 头
memcpy(header.chunk_id, "RIFF", 4);
header.chunk_size = wavbinsize + 44 - 8;
memcpy(header.format, "WAVE", 4);
// 填充 fmt 子块
memcpy(header.subchunk1_id, "fmt ", 4);
header.subchunk1_size = 16;
header.audio_format = 1; // PCM 编码
header.num_channels = num_channels;
header.sample_rate = sample_rate;
header.byte_rate = sample_rate * num_channels * bits_per_sample / 8;
header.block_align = num_channels * bits_per_sample / 8;
header.bits_per_sample = bits_per_sample;
// 填充 data 子块
memcpy(header.subchunk2_id, "data", 4);
header.subchunk2_size = wavbinsize;
}
void resize(uint32_t wavbinsize) {
header.chunk_size = wavbinsize + 44 - 8;
header.subchunk2_size = wavbinsize;
}
void dump() {
printf("chunk_id: %s\n", string(header.chunk_id, 4).c_str());
printf("chunk_size: %d\n", header.chunk_size);
printf("format: %s\n", string(header.format, 4).c_str());
printf("subchunk1_id: %s\n", string(header.subchunk1_id, 4).c_str());
printf("subchunk1_size: %d\n", header.subchunk1_size);
printf("audio_format: %d\n", header.audio_format);
printf("num_channels: %d\n", header.num_channels);
printf("sample_rate: %d\n", header.sample_rate);
printf("byte_rate: %d\n", header.byte_rate);
printf("block_align: %d\n", header.block_align);
printf("bits_per_sample: %d\n", header.bits_per_sample);
printf("subchunk2_id: %s\n", header.subchunk2_id);
printf("subchunk2_size: %d\n", header.subchunk2_size);
}
WAVHeader(uint32_t sample_rate, uint16_t bits_per_sample, uint16_t num_channels, uint32_t num_samples) {
initialize(sample_rate, bits_per_sample, num_channels, num_samples);
}
uint8_t* data() { return (uint8_t*)&header; }
size_t size() { return sizeof(header); }
};
void wavWriteVoice(string filename, uint32_t sample_rate, uint16_t bits_per_sample, uint16_t num_channels, const char* data, uint32_t size) {
fstream file;
WAVHeader wavHeader;
// logger->info("writeVoice filename:{} {} {} {} {}", filename, sample_rate, bits_per_sample, num_channels, size);
file.open(filename, fstream::in | fstream::out | fstream::binary);
if (!file.is_open()) {
file.open(filename, fstream::out | fstream::binary | fstream::trunc);
wavHeader.initialize(sample_rate, bits_per_sample, num_channels, 0);
file.seekp(0, ios::beg);
file.write((char*)wavHeader.data(), wavHeader.size());
file.close();
file.open(filename, fstream::in | fstream::out | fstream::binary);
}
// file.write(data, size);
#if 1
/**
* @brief 44
*/
file.seekp(0, ios::end);
file.write(data, size);
/**
* @brief
*/
uint32_t filesize = file.tellp();
file.seekp(4, ios::beg);
uint32_t chunk_size = filesize - 8;
file.write((char*)&chunk_size, 4);
file.seekp(40, ios::beg);
uint32_t subchunk2_size = filesize - 44;
file.write((char*)&subchunk2_size, 4);
#endif
file.close();
}
void sound_capture_callback(int32_t* voicedata, uint32_t len) {
printf("sound_capture_callback:%d\n", len);
wavWriteVoice("record.wav", 48000, 32, 1, (char*)voicedata, len * sizeof(int32_t));
}
int main(int argc, char const* argv[]) {
system("rm -rf record.wav");
error_code_t erro_code = sound_capturer_init("/dev/spidev1.0", 59, sound_capture_callback);
if (erro_code != ksp_success) {
sound_capturer_dump_last_error();

Loading…
Cancel
Save