espd/main/fifostream.c

136 lines
4 KiB
C

// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
// All rights reserved.
#include <string.h>
#include "esp_log.h"
#include "audio_error.h"
#include "audio_mem.h"
#include "audio_element.h"
#include "fifostream.h"
#include "audio_type_def.h"
static const char *TAG = "fifostream";
#define BUF_SIZE (100)
extern void pdmain_tick( void);
typedef struct fifostream {
int samplerate;
int channel;
short *s_buf;
int byte_num;
int at_eof;
} fifostream_t;
static esp_err_t fifostream_destroy(audio_element_handle_t self)
{
fifostream_t *fifostream = (fifostream_t *)audio_element_getdata(self);
audio_free(fifostream);
return ESP_OK;
}
static esp_err_t fifostream_open(audio_element_handle_t self)
{
ESP_LOGD(TAG, "fifostream_open");
fifostream_t *fifostream = (fifostream_t *)audio_element_getdata(self);
audio_element_info_t info = {0};
audio_element_getinfo(self, &info);
if (info.sample_rates
&& info.channels) {
fifostream->samplerate = info.sample_rates;
fifostream->channel = info.channels;
}
fifostream->at_eof = 0;
fifostream->s_buf = (short *)calloc(sizeof(short), BUF_SIZE/2);
if (fifostream->s_buf == NULL) {
ESP_LOGE(TAG, "calloc buffer failed. (line %d)", __LINE__);
return ESP_ERR_NO_MEM;
}
memset(fifostream->s_buf, 0, BUF_SIZE);
return ESP_OK;
}
static esp_err_t fifostream_close(audio_element_handle_t self)
{
ESP_LOGD(TAG, "fifostream_close");
fifostream_t *fifostream = (fifostream_t *)audio_element_getdata(self);
if (fifostream->s_buf == NULL) {
audio_free(fifostream->s_buf);
fifostream->s_buf = NULL;
}
return ESP_OK;
}
int phaseinc = 123;
static int fifostream_process(audio_element_handle_t self, char *in_buffer, int in_len)
{
static int cumsamps = 0;
fifostream_t *fifostream = (fifostream_t *)audio_element_getdata(self);
int ret = 0;
int r_size = 0;
if (fifostream->at_eof == 0) {
r_size = audio_element_input(self, (char *)fifostream->s_buf, BUF_SIZE);
}
if (r_size > 0) {
if (r_size != BUF_SIZE) {
fifostream->at_eof = 1;
}
fifostream->byte_num += r_size;
{
static int phase;
int i;
for (i = 0; i < r_size/sizeof(short); i++)
{
phase += phaseinc ;
fifostream->s_buf[i] = (phase >> 3);
}
cumsamps += r_size/sizeof(short);
while (cumsamps >= 128)
{
pdmain_tick();
cumsamps -= 128;
}
}
ret = audio_element_output(self, (char *)fifostream->s_buf, BUF_SIZE);
} else {
ret = r_size;
}
return ret;
}
audio_element_handle_t fifostream_init(fifostream_cfg_t *config)
{
if (config == NULL) {
ESP_LOGE(TAG, "config is NULL. (line %d)", __LINE__);
return NULL;
}
fifostream_t *fifostream = audio_calloc(1, sizeof(fifostream_t));
AUDIO_MEM_CHECK(TAG, fifostream, return NULL);
if (fifostream == NULL) {
ESP_LOGE(TAG, "audio_calloc failed for fifostream. (line %d)", __LINE__);
return NULL;
}
audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG();
cfg.destroy = fifostream_destroy;
cfg.process = fifostream_process;
cfg.open = fifostream_open;
cfg.close = fifostream_close;
cfg.buffer_len = 0;
cfg.tag = "fifostream";
cfg.task_stack = config->task_stack;
cfg.task_prio = config->task_prio;
cfg.task_core = config->task_core;
cfg.out_rb_size = config->out_rb_size;
cfg.stack_in_ext = config->stack_in_ext;
audio_element_handle_t el = audio_element_init(&cfg);
AUDIO_MEM_CHECK(TAG, el, {audio_free(fifostream); return NULL;});
fifostream->samplerate = config->samplerate;
fifostream->channel = config->channel;
audio_element_setdata(el, fifostream);
audio_element_info_t info = {0};
audio_element_setinfo(el, &info);
ESP_LOGD(TAG, "fifostream_init");
return el;
}