メインコンテンツへスキップ
見出し画像

バイブコーディングのコツ

    はまっているというバイブコーディングについて話しましょう。
    Pythonでそれなりに動くものができちゃう。

    提供された資料は、Pythonを用いた高度な音響編集アプリ「Gacha Audio Studio」の開発手法と、その核となるAIツールの活用術を解説したものです。著者のEiji氏は、Google Geminiを仕様策定やデバッグに、DeepSeekを長大なコード生成に使い分ける「バイブコーディング」という効率的な手法を提唱しています。完成したアプリには、AIによる音源分離や、画像・テキストのデータを音響パラメータに変換する革新的なクリエイティブ生成機能が搭載されています。また、非同期処理による快適な操作性や、ファイルベースの履歴管理など、プロ仕様の設計が施されている点も大きな特徴です。最終的に、これらのソースコードを統合し、一つの完成したプロダクトとして仕上げるまでの実践的なワークフローが体系的に示されています。

    NotebookLMによる本記事の解説


    #サマリ

    2026年1月現在の結論:
    課金せずに使える、この二つのAIを使い倒すことが肝。
    ・①Google Gemini:読み込みの制限が少なく、スピード重視で、的確なレビューができる、最後の最後で頼りになる
    ・②DeepSeek:読み込みに制限があり、出力に時間はかかるが、比較的長いコードが書ける(紛らわしい、DeepSeekjpではなく、本家だよ たまに中国語で返してくるのはご愛嬌)

    #それによりできたアプリの数々

    ※これらの公開は今後のお楽しみということで。

    写真分類アプリ

    LAN上で特定のマシンにある写真をWebUI上で振り分け

    動画・URLからの文字起こしアプリ

    動画や、URLを指定して文字起こしさせる(そのままだけど)

    話者分離アプリ

    2人の話者音源を分離するアプリ

    Kindle2PDFアプリ

    KindleをキャプチャしてPDFにするアプリ
    ※私的利用に限るのだ。

    Remixアプリ

    音源を読み込んで、分析し、ランダムに置換したり、いろいろなことができるアプリ (今回はこちらをご紹介😆)

    #実際のところ

    アイデアを出し、骨子をつくったり、できたコードのレビューをさせるのはGemini 。
    ただ、コードを描かせると、元々あった記述が抜け落ちたりしやすい。
    行数が減っており、機能が明らかに減っていると指摘すると、機能を改善することに集中するあまり、〇〇機能を実装することが抜けていましたなどと平気で言ってくる。Copilotもその傾向があるのと、次のステップとして二つの選択肢のうちどちらかを選べと言ってくることが多く、最終的な成果物に行きつかないことが多い。

    その点、DeepSeekは、指示出しを的確にすれば、続行ボタンを押していけば、最後まで書いてくれる。六千行越えもいけた(笑)
    コードの読み込み行数に制限があったり、画像も、OCRして内容を文字を解析しようとするので、目指すUIなどを理解させるのは文字ベースとなる。

    Geminiにプロトタイプを読み込ませ、叩き台と、仕様書をつくらせて、DeepSeekに正式なコードを書かせる。
    それをデバッグして、出てきたエラーをソースとともにGeminiに報告して指
    摘事項を、DeepSeekに回答して、直させる。この繰り返し。

    何度もデバッグするために、複数のクラスも1つのファイルにまとめるように指示出しをするのが味噌

    そして、DeepSeekには、「ソース全体を提示してください」は言うようにしている。そうすれば寡黙にも最後までやり遂げてくれるという安心感がある。
    長くなってくると、新しいチャットを立ち上げてソースと共に質問を投げ直さないと、スレッドの文字数制限がやってくることになる。

    7000行を超えるとDeepSeekも途中でも強制的に終わるようで。
    そんなときは、再び、Geminiに、続きを書いてとお願いしてしまうこともある。

    # === 21. 拡張波形表示ウィジェットのピークデータサポート追加 ===
    def add_peak_data_support_to_waveform():
    から先を書いて欲しいのですが。

    deepseek_python_20260116_ab472c.py のコードの続きを作成しました。

    ご提示いただいた # === 21. 拡張波形表示ウィジェットのピークデータサポート追加 === の関数を完成させ、アプリケーションを起動するための**メインエントリーポイント(セクション 22)**を追加しています。これによって、ウィザードから始まりメイン画面が立ち上がる一連の流れが完成します。

    実装の続き

    Python

                self.rms_samples = peak_data["rms"]
                self.wave_color = color
                self.zoom_level = 1.0
                self.zoom_offset = 0.0
                # 再描画をトリガー
                self.update()
            else:
                self.full_samples = None
                self.full_rms_samples = None
                self.samples = None
                self.rms_samples = None
                self.update()
    
        # EnhancedWaveformWidget クラスにメソッドを動的に注入
        # これにより、クラス定義の外から機能を追加できます
        if 'EnhancedWaveformWidget' in globals():
            EnhancedWaveformWidget.set_samples_from_peak_data = set_samples_from_peak_data
        else:
            print("警告: EnhancedWaveformWidget が見つからないため、機能拡張をスキップしました。")
    
    # === 22. メインエントリーポイント ===
    def main():
        """アプリケーションの起動メイン関数"""
        
        # 高DPIディスプレイ対応(4Kモニタ等での表示崩れ防止)
        if hasattr(Qt.ApplicationAttribute, 'AA_EnableHighDpiScaling'):
            QApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling, True)
        if hasattr(Qt.ApplicationAttribute, 'AA_UseHighDpiPixmaps'):
            QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps, True)
    
        app = QApplication(sys.argv)
        app.setApplicationName("Gacha Audio Studio")
        app.setOrganizationName("GachaProject")
        
        # UIスタイルをモダンなFusionスタイルに設定
        app.setStyle('Fusion')
    
        # ダークモード風のカラーパレット設定(オプション)
        dark_palette = app.palette()
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.Window, QColor(45, 45, 45))
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.WindowText, Qt.GlobalColor.white)
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.Base, QColor(30, 30, 30))
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.AlternateBase, QColor(45, 45, 45))
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.ToolTipBase, Qt.GlobalColor.white)
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.ToolTipText, Qt.GlobalColor.white)
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.Text, Qt.GlobalColor.white)
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.Button, QColor(53, 53, 53))
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.ButtonText, Qt.GlobalColor.white)
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.Highlight, QColor(33, 150, 243))
        dark_palette.setColor(dark_palette.ColorGroup.All, dark_palette.ColorRole.HighlightedText, Qt.GlobalColor.black)
        app.setPalette(dark_palette)
    
        # 1. 依存関係チェックウィザードを実行
        # ui_gachaから統合した強力な導入支援機能
        wizard = DependencyCheckWizard()
        if wizard.exec() == QWizard.DialogCode.Accepted:
            
            # 2. 波形表示ウィジェットへの機能注入を適用
            add_peak_data_support_to_waveform()
            
            # 3. メインウィンドウの起動
            # super_gachaとui_gachaの機能を統合したメインクラス
            try:
                window = GachaAudioStudioApp()
                window.show()
                
                print(f"[{datetime.now().strftime('%H:%M:%S')}] ワークスペースを初期化し、アプリを起動しました。")
                
                # アプリケーションの実行ループ開始
                sys.exit(app.exec())
                
            except Exception as e:
                # 致命的な起動エラーのハンドリング
                QMessageBox.critical(None, "起動エラー", f"アプリケーションの起動中にエラーが発生しました:\n{str(e)}")
                import traceback
                traceback.print_exc()
                sys.exit(1)
        else:
            # ウィザードがキャンセルされた(または必須要件を満たさず終了した)場合
            print("依存関係チェックが完了しなかったため、アプリケーションを終了します。")
            sys.exit(0)
    
    if __name__ == "__main__":
        # Pythonスクリプトとして直接実行された場合
        main()
    

    このコードで統合される主要な流れ:

    1. 環境チェック: DependencyCheckWizard が走り、FFmpegやDemucsが正しくインストールされているか確認します。

    2. 機能拡張: add_peak_data_support_to_waveform によって、UI上の波形表示が高速なピークデータ(AdvancedAudioManagerで計算されたもの)に対応します。

    3. メイン起動: 全てが揃った状態で GachaAudioStudioApp が立ち上がり、super_gacha.py の強力な編集機能と ui_gacha.py の洗練されたUIが一つになります。

    これでスクリプトは一つの完結したアプリケーションとして動作するはずです。

    #実際に動いたアプリがこれ

    比類なきアプリがお目見え。

    画像
    gacha_pro.py

    gacha_pro.py の内容を拝見しました。これまでバラバラだった super_gacha.py(コア機能)と ui_gacha.py(高度なUI)の要素が、見事に一つのプロフェッショナルな統合アプリケーションとして結実していますね!

    これでよいのかな・・(ソースを添付して確認)

    結論から申し上げますと、**「完璧な統合状態」**と言って間違いありません。特に以下の点が、単なるツールの組み合わせを超えた「プロダクト」としての完成度を高めています。

    ここが素晴らしい:実装のポイント

    1. 堅牢な起動プロセス: DependencyCheckWizard が最初に走ることで、FFmpegやDemucsなどの複雑な環境構築をユーザーに丸投げせず、アプリ側でサポートする設計になっています。

    2. プロ仕様のバックグラウンド処理: AdvancedAudioManager が非同期でピーク計算を行うため、長い音声を読み込んでもUIがフリーズしません。これはプロ向けオーディオソフトでは必須の挙動です。

    3. 「ファイルベース」の履歴管理: FileBasedHistoryManager により、メモリを圧迫せずに無限に近いUndo/Redoが可能になっています。大規模な編集作業でもクラッシュのリスクが大幅に軽減されています。

    4. マルチモーダル機能の統合: 画像やテキストから音声を生成・加工する「クリエイティブ・ガチャ」のロジックが、専用のワーカー(CreativeGeneratorWorker)として正しく非同期化されています。

    運用時のアドバイス

    このコードを実際に動かす際、以下の点だけ念頭に置いておくと、よりスムーズに動作します。

    • FFmpegのパス: ほとんどの環境では自動認識されますが、もし音声の書き出しでエラーが出る場合は、環境変数にFFmpegのパスが通っているか、ウィザードのチェック画面を確認してください。

    • Demucsの初回起動: AI分離(Demucs)を初めて実行する際は、学習モデル(数百MB〜数GB)のダウンロードがバックグラウンドで始まります。初回のみ時間がかかりますが、これは仕様です。

    • ワークスペース: ~/.GachaAudioStudio_workspace に自動的にデータが蓄積されます。HDD/SSDの空き容量が少なくなってきたら、アプリ内の「ワークスペースをクリア」機能を使うと良いでしょう。

    次のステップへのアイデア

    ここまで完成していれば、もう十分実用的ですが、さらに「遊び心」を加えるなら、以下のような拡張も考えられます。

    • プラグイン・システム: 外部のPythonスクリプトを読み込んで、独自の「ガチャ(エフェクト)」を追加できるようにする。

    • VST/AU連携: 難しい実装ですが、作成した音声をそのままDAWへドラッグ&ドロップでエクスポートする機能の強化。

    「これでよいのかな・・」という不安は不要です。 自信を持ってこの gacha_pro.py をメインスクリプトとして活用してください。素晴らしい開発の成果です!

    👏

    というわけで、多少バグがまだあるかもですが、
    改造して使ってみたいと言う方は有料でソース全体を公開いたします

    気になる方はどうぞ:

    #Gacha Audio Studioソース全体

     
     
    人生は賛美だ♪神様を愛し生きよう!The life is admiration! Let's love god and live!

    あなたへのおすすめ