0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Node.js で node-speaker を使って PCM のオーディオデータをスピーカーから再生してみる

Last updated at Posted at 2025-05-22

はじめに

以下の「node-speaker」を使って、Node.js 上で PCM(Pulse-Code Modulation)オーディオデータを、直接スピーカーから再生する、という内容を試しました。

●speaker - npm
 https://www.npmjs.com/package/speaker

image.png

これを試した背景

今回の内容をやろうと思った背景は、Google I/O 2025 で発表された以下の音楽生成を使い、Node.js で受信したデータから音を鳴らす、ということをやりたかったためです。

●Music generation | Gemini API | Google AI for Developers
 https://ai.google.dev/gemini-api/docs/music-generation

●Lyria RealTime - Google DeepMind
 https://deepmind.google/models/lyria/realtime/

ちなみに、上記のサンプルコード内の音を鳴らす処理は「// Application logic: buffer and play using Web Audio API etc.」と書いてあり、何らか自分で用意する必要がある状態でした。

image.png

実際に試していく

今回、node-speaker は初めて使うので、「シンプルな音のデータを単純に鳴らす」ということだけやってみます。

まず公式ページ上のサンプルを見てみると、以下が書かれています。

const Speaker = require('speaker');

// Create the Speaker instance
const speaker = new Speaker({
  channels: 2,          // 2 channels
  bitDepth: 16,         // 16-bit samples
  sampleRate: 44100     // 44,100 Hz sample rate
});

// PCM data from stdin gets piped into the speaker
process.stdin.pipe(speaker);

これだけだと、音は鳴らない状態です。

音を鳴らす

下準備

今回の内容を試す下準備として、node-speaker をインストールします。
※ ちなみに、自分がこれを試している環境は Mac です

npm install speaker

自前の実装

鳴らす音の元データを作る部分と、それを鳴らす部分とを実装してみました。

import Speaker from "speaker";

const speaker = new Speaker({
  channels: 2,
  bitDepth: 16,
  sampleRate: 44100,
  signed: true,
  float: false,
});

const durationSec = 2;
const freq = 440; // Hz
const sampleRate = 44100;
const totalSamples = sampleRate * durationSec;
let i = 0;

// 1サンプルあたり4バイト (ステレオ×16bit)
const CHUNK_SIZE = 1024; // サンプル数
function writeChunk() {
  if (i >= totalSamples) {
    speaker.end();
    return;
  }
  const count = Math.min(CHUNK_SIZE, totalSamples - i);
  const buf = Buffer.alloc(count * 4);
  for (let j = 0; j < count; j++, i++) {
    const t = i / sampleRate;
    const v = Math.round(Math.sin(2 * Math.PI * freq * t) * 32767);
    buf.writeInt16LE(v, j * 4); // 左
    buf.writeInt16LE(v, j * 4 + 2); // 右
  }
  if (!speaker.write(buf)) {
    speaker.once("drain", writeChunk);
  } else {
    setImmediate(writeChunk);
  }
}

writeChunk();

これを実行すると、短い時間、シンプルな音が鳴るのが確認できました。

とりあえず、Node.js で node-speaker を使ってスピーカーから音を鳴らす、という内容は実現できました。

【追記】

その後、当初やりたかった「Gemini API での音楽生成に使う」というのも、無事に実装できました。

(やたらと文字が出力されているのは、実装を試す途中でエラーが出たり、エラーは出ないけど音が鳴らなかったりという状態になって、データ受信や各処理の動作を確認するデバッグ情報を出してるためです)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?