Skip to main content

Singing in client mode

Client-mode singing synthesis uses official VOICEVOX engine endpoints: sing_frame_audio_query and frame_synthesis. Unlike talk mode, you build a Score and Note set first.

Prerequisites

docker pull voicevox/voicevox_engine:cpu-latest
docker run --rm -p '127.0.0.1:50021:50021' voicevox/voicevox_engine:cpu-latest

Create Score and Note

use Revolution\Voicevox\Song\Note;
use Revolution\Voicevox\Song\Score;

$score = Score::make([
    Note::make(length: 15),
    Note::make(length: Note::len(ticks: 480, bpm: 120), lyric: 'ド', key: 60),
    Note::make(length: Note::len(480, 120), lyric: 'レ', key: 62),
    Note::make(length: Note::len(960, 120), lyric: 'ミ', key: 64),
    Note::make(length: 2),
]);
ParameterTypeDescription
lengthintFrame length
lyricstringLyrics text. Empty string or omitted value means rest
keyint|nullMIDI note number
Use Note::len($ticks, $bpm) to calculate frame lengths from MIDI ticks and BPM. A quarter note at 480 ticks is a practical default.

Basic usage

use Revolution\Voicevox\Song\Note;
use Revolution\Voicevox\Song\Score;
use Revolution\Voicevox\Voicevox;

$score = Score::make([
    Note::make(length: 15),
    Note::make(length: Note::len(480, 120), lyric: 'ド', key: 60),
    Note::make(length: Note::len(480, 120), lyric: 'レ', key: 62),
    Note::make(length: Note::len(960, 120), lyric: 'ミ', key: 64),
    Note::make(length: 2),
]);

$response = Voicevox::song($score, teacher: 6000)
    ->generate(id: 3001);

$response->storeAs('client', 'song.wav');

teacher and id

  • teacher: style ID for sing_frame_audio_query (currently 6000 only, so default is 6000)
  • generate(id:): style ID for frame_synthesis
Get available singing speakers with singers().
use Revolution\Voicevox\Voicevox;

$singers = Voicevox::singers();

Tune F0 and volume with tap()

In song mode, tap() is especially useful: adjust SongAudioQuery, then keep chaining to generate().
use Revolution\Voicevox\Client\SongAudioQuery;
use Revolution\Voicevox\Voicevox;

$response = Voicevox::song($score, teacher: 6000)
    ->tap(function (SongAudioQuery $song) {
        $song->sync();
    })
    ->generate(id: 3001);
If you update values individually, use this order: F0 first, volume second.
->tap(function (SongAudioQuery $song) {
    $song->updateF0();
    $song->updateVolume();
})
tap() is also useful when you edit notes and re-sync.
->tap(function (SongAudioQuery $song) {
    $song->score->notes[2] = Note::make(length: Note::len(480, 120), lyric: 'ファ', key: 65);
    $song->sync();
})
See tap() helper and Tappable trait for the core pattern. VOICEVOX for Laravel is a clear real-world use case.

Next pages

Score and Note Deep Dive

Review frame-length math and practical JSON chart management.

Native Song

Use the same Score in native FFI mode.

VOICEVOX Core for PHP Usage

Review standalone core synthesis flow.
Last modified on May 23, 2026