void AudioHandler::_audio_task() { std::array<int16_t, 512> audioBuffer; while(true) { while(currentCassettes.empty()) xTaskNotifyWait(0, 0, nullptr, portMAX_DELAY); audioBuffer.fill(0); for(uint16_t i=0; i<audioBuffer.size(); i++) { for(auto &c : currentCassettes) audioBuffer[i] += c.get_chunk(); } size_t written_samples = 0; i2s_write(i2s_port, audioBuffer.data(), 1024, &written_samples, portMAX_DELAY); for(auto i=currentCassettes.begin(); i<currentCassettes.end(); i++) { if(i->is_done()) currentCassettes.erase(i); } if(currentCassettes.empty()) i2s_zero_dma_buffer(i2s_port); } }
static void setup_triangle_sine_waves(int bits) { int *samples_data = malloc(((bits+8)/16)*SAMPLE_PER_CYCLE*4); unsigned int i, sample_val; double sin_float, triangle_float, triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; size_t i2s_bytes_write = 0; printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits+8)/16)*SAMPLE_PER_CYCLE*4); triangle_float = -(pow(2, bits)/2 - 1); for(i = 0; i < SAMPLE_PER_CYCLE; i++) { sin_float = sin(i * PI / 180.0); if(sin_float >= 0) triangle_float += triangle_step; else triangle_float -= triangle_step; sin_float *= (pow(2, bits)/2 - 1); if (bits == 16) { sample_val = 0; sample_val += (short)triangle_float; sample_val = sample_val << 16; sample_val += (short) sin_float; samples_data[i] = sample_val; } else if (bits == 24) { //1-bytes unused samples_data[i*2] = ((int) triangle_float) << 8; samples_data[i*2 + 1] = ((int) sin_float) << 8; } else { samples_data[i*2] = ((int) triangle_float); samples_data[i*2 + 1] = ((int) sin_float); } } i2s_set_clk(I2S_NUM, SAMPLE_RATE, bits, 2); //Using push // for(i = 0; i < SAMPLE_PER_CYCLE; i++) { // if (bits == 16) // i2s_push_sample(0, &samples_data[i], 100); // else // i2s_push_sample(0, &samples_data[i*2], 100); // } // or write i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); free(samples_data); }