Facebookでトランジスタ1個で波形整形すると良い、とアドバイスをいただいたのですが、アナログスキルがないので、部品頼みで整形しました(手元のオペアンプは遅すぎてコンパレータとして働いてくれませんでした)。
昔懐かしいシュミットトリガSN74HC14を使います。私が子供の頃TTLのSN74N/Aシリーズは5v専用だったんですが現在のHCシリーズはCMOSなので電源電圧範囲が広く、それにあわせてスレッショルドが変わるので便利です。
接続はESP32から3.3vとGndとGPIO25,26をつなぎます。SN74HC14の使っていないピンは全部GNDに落として置きます(基本のお約束)。HC14はインバータなので2段にしています(あんまり意味ないんですが)。HC14の遅延は最大でも20nS程度なので、今回の用途では問題ありません(と断言したら怒られるかな)。
出てきた波形はこちらです。黄色がGPIO出力、水色がシュミットで整形後です(プローブx10)。
結果として、内蔵DACよりもかなり良い感じの音になります。
でも、無音時のホワイトノイズが消えてくれません。あと一歩です。
うーん、アナログはわからない……。ソースコードはこんな感じです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Sound | |
// | |
#include "driver/i2s.h" | |
#include "driver/gpio.h" | |
#include "ching.h" | |
#include "clap.h" | |
#include "cymbal.h" | |
#include "voice.h" | |
const i2s_port_t I2S_NUM = (i2s_port_t)0; | |
const i2s_bits_per_sample_t BITS_PER_SAMPLE = (i2s_bits_per_sample_t)16; | |
// PDM | |
void set_16k_16() { | |
i2s_set_pin(I2S_NUM, NULL); | |
i2s_config_t i2s_config; | |
i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_PDM); // Only TX | |
i2s_config.sample_rate = 16000; | |
i2s_config.bits_per_sample = BITS_PER_SAMPLE; | |
i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT; //right channels | |
// i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; //right left | |
i2s_config.communication_format = I2S_COMM_FORMAT_PCM; | |
i2s_config.dma_buf_count = 4; | |
i2s_config.dma_buf_len = 1024; | |
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1 | |
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL); | |
} | |
void setup() | |
{ | |
Serial.begin(115200); | |
set_16k_16(); | |
Serial.println("setup end"); | |
} | |
int iSound = 0; | |
void loop() | |
{ | |
Serial.println("ching"); | |
i2s_write_bytes(I2S_NUM, (const char *)ching, sizeof(ching), portMAX_DELAY); | |
delay(500); | |
Serial.println("clap"); | |
i2s_write_bytes(I2S_NUM, (const char *)clap, sizeof(clap), portMAX_DELAY); | |
delay(500); | |
Serial.println("cymbal"); | |
i2s_write_bytes(I2S_NUM, (const char *)cymbal, sizeof(cymbal), portMAX_DELAY); | |
delay(500); | |
Serial.println("voice"); | |
i2s_write_bytes(I2S_NUM, (const char *)voice, sizeof(voice), portMAX_DELAY); | |
delay(500); | |
} | |
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。