編集履歴一覧に戻る
chrmlinux03のアイコン画像

chrmlinux03 が 2023年12月14日19時53分18秒 に編集

コメント無し

本文の変更

# はじめに はいまた投稿だよ リナちゃん💕です SPRESENSE2023 あと60日切りましたねっ 今回はSPRESENSEのAudio機能を切り崩してまいります # もくてき mp3/wav/raw ファイルのDual_Playerとかのサンプルはあるんですけど そのFileから取得されたDataと映像のリンクが面倒なの sampleは膨大なのに ちょっとわかりづらい構成(goto とかあるし)になってて まぁ専門の方々なら読めるんだろうけど # rawふぁいるの構成 ぢゃぁ非圧縮のファイルを考えて rawファイルに目を向けて見る CD音質と同じファイルフォーマットなら freq 44.1000Hz 16bit 2ch なの つまり こういう計算式になるよね ![キャプションを入力できます](https://camo.elchika.com/709181b44adaadb8eafb0b3d89b91009624f1562/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38373864346139632d633739622d343839652d383830322d6137626538616332663037302f36356536363635642d336666362d343064642d393237342d336635623234616330366564/) 1秒間あたりのバイト数はなんと 176,400 Byte💦 これを3分くらい再生するわけですから  ![キャプションを入力できます](https://camo.elchika.com/7a8f87851949a06e9be3a2362a6d5ad3b82304e5/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38373864346139632d633739622d343839652d383830322d6137626538616332663037302f32373833646562392d363731632d343131622d613936392d393738373136326130366636/) 3分あたりのバイト数はなんと 31MegaByte💦 この秒以下の時間で31MegaByteをSPRESENSE のDSPに送るわけですからもう大変は事です ちなみに Audio 機能は SubCore では動きません 出典:Spresenseハードウェアドキュメント ![キャプションを入力できます](https://camo.elchika.com/8cbe43b568edee639a04bd62440077181e53f3d2/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38373864346139632d633739622d343839652d383830322d6137626538616332663037302f61646531356137332d353538612d343333662d626163392d663234373637636135366535/) # しんぷるえふあぃえふぉ? 音楽は音声ファイル(theFile)を読み込んで一旦 DSPのsimpleFIFO に送られるの FIFO だから最初に書いたものから最初に押しだされるって感じ ※bufが5コの場合 setup() {     -> [4][3][2][1][0] 左からデータが積まれて行く(まだ再生はしない) } loop() {     -> [5][4][3][2][1] [0] が再生されて [5] が積まれる     -> [6][5][4][3][2] [1] が再生されて [6] が積まれる } SPRESENSE の DSP はそのあたりは良くできていて simpleFIFOがエラーを返してくれるのね だからそのエラーの感じで simpleFIFO を微妙にHackすれば 音は鳴り続けるという事までは分かった たま~に 1個入れたのに 2個3個とか再生されたり←今ここ苦戦中 # お試し 上のloopのDSPに送るタイミングで間に映像を流せば 多分なるよね~って作ったのがこれ simpleFIFO の現在のポインタの位置とか判ればもうちょっと同期出来るんですけどね

-

![円状に波形効果を描画する](https://twitter.com/chrmlinux03/status/1601117185078079491?s=20&t=Cam4dJaVydck_arKy0xQAQ)

+

https://twitter.com/chrmlinux03/status/1601117185078079491?s=20

# さいごに 完全なるソースの公開は来年までお待ちください 今回は音声データの可視化のみお楽しみ頂ければと考えています ぢゃ また投稿するね💕 # 可視化コード データは44.1kHzのサンプリングレート、16ビットのビット深度、2チャンネルのオーディオデータは、アナログ信号を44,100回/秒でサンプリングし、各サンプルを16ビットで表現し、左右の2つのチャンネルでデジタル化され16ビットの符号付整数データを-1.0から1.0の範囲に変換(スケーリング)されてます ```arduino:drawRadialEffectWav.hpp void drawRadialEffectWav(LGFX_Sprite *sprite, float *audioBuffer, uint32_t audioBufferSize, uint8_t audioDataLength, uint8_t audioChannels, uint16_t drawPoints, int16_t pitch, int16_t space) { // Definition of the Point structure struct Point { int16_t x; int16_t y; float pwr; }; // Calculate the number of samples int16_t samples = (audioBufferSize / audioDataLength); // Number of samples per draw point int16_t samplesPerDrawPoint = samples / drawPoints; // Sprite width and height int16_t spriteWidth = sprite->width(), spriteHeight = sprite->height(); // Half of the sprite width and height int16_t halfSpriteWidth = spriteWidth >> 1, halfSpriteHeight = spriteHeight >> 1; // Calculate the radius (considering space) int16_t radius = min(halfSpriteWidth, halfSpriteHeight) - space; // Array to store coordinates and power for draw points Point drawPointsArray[drawPoints][audioChannels]; // Calculate coordinates and power for draw points based on audio data for (int ch = 0; ch < audioChannels; ch++) { for (int i = 0; i < drawPoints; i++) { float angle = radians(i * (360.0 / drawPoints)); int16_t index = i * samplesPerDrawPoint + ch; drawPointsArray[i][ch] = { halfSpriteWidth + (radius + audioBuffer[index] * pitch) * cos(angle), halfSpriteHeight + (radius + audioBuffer[index] * pitch) * sin(angle), audioBuffer[index] }; } } // Draw circles at the calculated coordinates for (int ch = 0; ch < audioChannels; ch++) { for (int i = 0; i < drawPoints; i++) { sprite->fillCircle(drawPointsArray[i][ch].x, drawPointsArray[i][ch].y, drawPointsArray[i][ch].pwr * random(20), colorPalette[random(RCOLOR_MAX)]); } } } ```