広告枠を募集中 ご相談ください

Uberduck API を活用して AI ラップおよび歌声をプログラム生成する方法

365Finds Editorial
Wiki 記事 11,430 本収録

あなたの AI で 365 Wiki を使う

下のプロンプトをコピーして、普段使っている AI に貼り付け、そのまま質問してください。

完全版 Skill をダウンロード

まずはプロンプトでお試しください。よく使う場合は完全版 365Wiki Skill をインストールすると、毎回貼り付ける必要がありません。普段使う AI がなければ、Gemini や Microsoft Copilot のウェブ版でも使えます。

インタラクティブな音楽アプリ、ゲーム NPC の自動歌唱、またはバーチャル配信者(VTuber)向けのオーディオ合成システムを構築する開発者にとって、ブラウザ上の手動操作画面は大きなボトルネックになります。手動の UI 操作では、本番環境の自動化ワークフローや高並列バッチ合成に対応できません。Uberduck は公式の REST API を提供しており、エンジニアがコードから直接、リズムと音程を持ったボーカル音声を自動生成できる環境を整えています。

Uberduck API を用いてラップや歌唱ボーカルを生成するには、HTTP Basic 認証、用途に応じた生成エンドポイントの選定(ビート同期型の /tts/freestyle、ピッチ制御型の /speak、または音声変換 /tts/convert)、そして /speak-status による非同期ポーリング処理の 3 つの要素を設計する必要があります。


1. 認証方式とリクエストの基本構造

Uberduck の REST API は、標準的な HTTP Basic 認証を採用しています。ダッシュボードで取得した API Key(ユーザー名)と API Secret(パスワード)をコロンで連結し、Base64 エンコードした文字列をリクエストヘッダーに設定します。

認証ヘッダーの構成

  1. Uberduck のアカウント設定画面で API Key と API Secret を発行します。
  2. HTTP の Authorization ヘッダーを以下のように構築します:
    Authorization: Basic base64(API_KEY:API_SECRET)
    
  3. API のベース URL は https://api.uberduck.ai です。
import base64
import os

API_KEY = os.getenv("UBERDUCK_API_KEY", "your_api_key")
API_SECRET = os.getenv("UBERDUCK_API_SECRET", "your_api_secret")

def get_auth_headers():
    token = base64.b64encode(f"{API_KEY}:{API_SECRET}".encode("utf-8")).decode("utf-8")
    return {
        "Authorization": f"Basic {token}",
        "Content-Type": "application/json"
    }

2. 3 種類のボーカル合成モード

リズム重視のラップとメロディアスな歌唱では必要な制御が異なります。Uberduck は以下の 3 つのアプローチを提供しています:

合成モード主要エンドポイント主なパラメータ最適なユースケース
テキスト・トゥ・ラップ(Freestyle)POST /tts/freestylelyrics, bpm, backing_track, voice または voicemodel_uuidビートに同期したラップ楽曲の生成;即興フリースタイル;インタラクティブな歌詞演出
パラメータ指定型ピッチ・時間軸合成POST /speakspeech, voicemodel_uuid, pitch, duration, paceMIDI データや譜面情報に基づき、音素ごとのピッチ曲線と長さを精密制御する楽曲合成
音声変換(Voice-to-Voice)POST /tts/convertvoicemodel_uuid, input(音声 URL), pitch_shift自然なビブラートや抑揚を保ったメロディ歌唱;ガイドボーカル音源からのキャラクター声変換

3. テキスト・トゥ・ラップ(Freestyle)パイプラインの構築

/tts/freestyle はラップに特化したエンドポイントであり、設定したテンポ(BPM)とバッキングトラックのリズムに合わせて歌詞を自動的にアラインメントします。

ステップ 1:利用可能なバッキングトラックの取得

公式に提供されているビート音源と歌詞を同期させたい場合は、一覧取得エンドポイントを呼び出します:

import requests

def list_backing_tracks():
    url = "https://api.uberduck.ai/reference-audio/backing-tracks?detailed=true"
    response = requests.get(url, headers=get_auth_headers())
    response.raise_for_status()
    return response.json()  # トラック UUID、BPM、ジャンル情報を含むリスト

ステップ 2:(任意)押韻歌詞の自動生成

ユーザーの入力テーマから即座にラップ歌詞を生成したい場合は、/tts/lyrics エンドポイントを利用できます(または LLM の出力を 2 次元配列形式に整形します):

def generate_lyrics(subject, lines=4):
    url = "https://api.uberduck.ai/tts/lyrics"
    payload = {
        "subject": subject,
        "lines": lines
    }
    response = requests.post(url, json=payload, headers=get_auth_headers())
    response.raise_for_status()
    return response.json()  # 構造化された歌詞行

ステップ 3:Freestyle 生成リクエストの送信

二次元配列として構成した歌詞、目標 BPM、トラック UUID、ボイスモデル ID を API に送信します:

def generate_rap_vocal(lyrics_matrix, bpm=90, backing_track_uuid=None, voice="zwf"):
    url = "https://api.uberduck.ai/tts/freestyle"
    payload = {
        "lyrics": lyrics_matrix,  # 例: [["コードが走るビートの波に乗って", "APIコールが響き渡るフロア"]]
        "bpm": bpm,
        "voice": voice,
        "format": "json"
    }
    if backing_track_uuid:
        payload["backing_track"] = backing_track_uuid

    response = requests.post(url, json=payload, headers=get_auth_headers())
    response.raise_for_status()
    data = response.json()
    return data["uuid"]  # 非同期タスクの UUID を取得

4. ピッチ時間軸と歌唱ボーカルの設定

メロディを伴う歌唱では、滑らかな音高遷移と音素の持続時間が不可欠です。Uberduck では 2 つの方法でこれを実現できます:

アプローチ A:/speak によるピッチ配列と持続時間の制御

詳細な制御に対応したボイスモデル(GET /voices/{voicemodel_uuid}/detail のレスポンスで controls: true となっているモデル)では、/speak エンドポイントに pitch(音高配列)と duration(時間配列)を渡すことができます:

def generate_singing_notes(speech_text, voicemodel_uuid, pitch_curve, duration_curve):
    """
    pitch_curve: 各音素の目標ピッチ(F0 または半音単位)の数値配列
    duration_curve: 各音素の継続時間を表す数値配列
    """
    url = "https://api.uberduck.ai/speak"
    payload = {
        "speech": speech_text,
        "voicemodel_uuid": voicemodel_uuid,
        "pitch": pitch_curve,
        "duration": duration_curve,
        "pace": 1.0
    }
    response = requests.post(url, json=payload, headers=get_auth_headers())
    response.raise_for_status()
    return response.json()["uuid"]

アプローチ B:音声変換(V2V)による高品質な歌唱生成

テキストから直接音素単位のピッチ曲線を算出するのは複雑であり、機械的な響きになりやすい傾向があります。そのため、商用音楽アプリでは Voice-to-Voice(音声変換) が広く使われています。 MIDI 音源や人間の仮歌(ガイドボーカル)を入力として POST /tts/convert に渡し、pitch_shift でキーを調整することで、自然な歌声を再現できます:

def convert_guide_vocal_to_singer(guide_audio_url, target_voice_uuid, semitone_shift=0):
    url = "https://api.uberduck.ai/tts/convert"
    payload = {
        "input": guide_audio_url,
        "voicemodel_uuid": target_voice_uuid,
        "pitch_shift": semitone_shift
    }
    response = requests.post(url, json=payload, headers=get_auth_headers())
    response.raise_for_status()
    return response.json()["uuid"]

5. 非同期処理とステータスポーリングの仕組み

音声ニューラルネットワークのレンダリングには数秒〜十数秒の演算を要するため、API はリクエスト時に即座にジョブ ID(uuid)を返します。バックエンド側で /speak-status エンドポイントを定期的にポーリングする必要があります。

import time

def poll_render_completion(job_uuid, max_attempts=30, delay_seconds=2):
    status_url = f"https://api.uberduck.ai/speak-status?uuid={job_uuid}"
    headers = get_auth_headers()
    
    for attempt in range(max_attempts):
        response = requests.get(status_url, headers=headers)
        response.raise_for_status()
        data = response.json()
        
        # 失敗判定
        if data.get("failed_at"):
            raise RuntimeError(f"ボーカル生成に失敗しました: {data}")
            
        # 完了判定
        if data.get("finished_at"):
            audio_url = data.get("path")
            return audio_url  # 生成された WAV ファイルの CDN URL
            
        time.sleep(delay_seconds)
        
    raise TimeoutError("音声生成がタイムアウトしました。")

6. エンドツーエンドの統合スクリプト例

認証、リクエスト送信、ステータスポーリング、ファイル保存までを網羅した Python スクリプトは以下のとおりです:

import requests
import base64
import time
import os

UBERDUCK_API_KEY = os.getenv("UBERDUCK_API_KEY")
UBERDUCK_API_SECRET = os.getenv("UBERDUCK_API_SECRET")

HEADERS = {
    "Authorization": f"Basic {base64.b64encode(f'{UBERDUCK_API_KEY}:{UBERDUCK_API_SECRET}'.encode()).decode()}",
    "Content-Type": "application/json"
}

def create_rap_track(lyrics, bpm=95, voice="zwf", output_file="vocal_output.wav"):
    # 1. ラップ生成ジョブの送信
    print("ボーカル生成リクエストを送信中...")
    freestyle_url = "https://api.uberduck.ai/tts/freestyle"
    payload = {
        "lyrics": lyrics,
        "bpm": bpm,
        "voice": voice,
        "format": "json"
    }
    
    resp = requests.post(freestyle_url, json=payload, headers=HEADERS)
    resp.raise_for_status()
    task_id = resp.json()["uuid"]
    print(f"ジョブ開始 UUID: {task_id}")
    
    # 2. 完了ポーリング
    status_url = f"https://api.uberduck.ai/speak-status?uuid={task_id}"
    audio_url = None
    for _ in range(40):
        time.sleep(2)
        status_resp = requests.get(status_url, headers=HEADERS)
        status_resp.raise_for_status()
        status_data = status_resp.json()
        
        if status_data.get("failed_at"):
            raise RuntimeError("サーバー側でレンダリングエラーが発生しました。")
        if status_data.get("finished_at"):
            audio_url = status_data.get("path")
            print(f"生成完了 URL: {audio_url}")
            break
            
    if not audio_url:
        raise TimeoutError("処理が 80 秒を超過したため中止しました。")
        
    # 3. 音声ファイルのダウンロード
    audio_data = requests.get(audio_url).content
    with open(output_file, "wb") as f:
        f.write(audio_data)
    print(f"ファイルを保存しました: {output_file}")
    return output_file

if __name__ == "__main__":
    bars = [
        ["自動生成ラインが描くグルーヴの軌道", "コードがつなぐ新しい音楽の波動"],
        ["完璧なテンポで駆け抜けるBPM", "Uberduck APIが切り拓くサウンドの地平"]
    ]
    create_rap_track(lyrics=bars, bpm=95)

7. 本番環境での運用ポイントと技術的トレードオフ

システムを本番稼働させる際は、以下の考慮事項が重要です:

参考文献