#include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include static QueueHandle_t soundQueue; //powers of 2 plzthx #define BUFLEN 2048 #define IO_AMP_DIS 2 static uint8_t buf[BUFLEN]; static volatile int wp=256, rp=0; static int ampPowerTimeout=0; static int bufLen() { return (wp-rp)&(BUFLEN-1); } int sndDone() { //1 when stuff can be written to buffer // printf("sndpoll %d\n", bufLen()); return bufLen()<(BUFLEN-400); } volatile static int myVolume; #define SND_CHUNKSZ 128 void sndTask(void *arg) { uint32_t tmpb[SND_CHUNKSZ]={0}; printf("Sound task started.\n"); while (1) { int volume=(int)myVolume; for (int j=0; j>(7-volume)); s=s/16; tmpb[j]=((s+128)<<8)+((s+128)<<24); rp++; if (rp>=BUFLEN) rp=0; } i2s_write_bytes(0, (char*)tmpb, sizeof(tmpb), portMAX_DELAY); // printf("snd %d\n", rp); } } int sndPush(uint8_t *data, int volume) { while (!sndDone()) usleep(1000); myVolume=volume; if (volume) { for (int i=0; i<370; i++) { buf[wp]=*data; data+=2; wp++; if (wp>=BUFLEN) wp=0; } gpio_set_level(IO_AMP_DIS, 0); ampPowerTimeout=10; } else { //muted for (int i=0; i<370; i++) { buf[wp++]=128; if (wp>=BUFLEN) wp=0; } ampPowerTimeout--; if (ampPowerTimeout==0) gpio_set_level(IO_AMP_DIS, 1); } return 1; } void sndInit() { i2s_config_t cfg={ .mode=I2S_MODE_DAC_BUILT_IN|I2S_MODE_TX|I2S_MODE_MASTER, .sample_rate=22200, .bits_per_sample=16, .channel_format=I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format=I2S_COMM_FORMAT_I2S_MSB, .intr_alloc_flags=0, .dma_buf_count=8, .dma_buf_len=1024/8 }; i2s_driver_install(0, &cfg, 4, &soundQueue); i2s_set_pin(0, NULL); i2s_set_dac_mode(I2S_DAC_CHANNEL_LEFT_EN); i2s_set_sample_rates(0, cfg.sample_rate); gpio_config_t io_conf_amp={ .intr_type=GPIO_INTR_DISABLE, .mode=GPIO_MODE_OUTPUT, .pull_up_en=1, .pin_bit_mask=(1<