Raspberry Pi + JackでBluetoothレシーバーとソフトシンセを同時に鳴らす

Claudeにスクリプト作ってもらった。このファイルを作って実行すると、必要なものを全てインストールして、```start-jack-bluetooth.sh```と```stop-jack-bluetooth.sh```っていう2つのスクリプトが生成される。めっちゃ便利でしょ。

<details><summary>setup-jack-bluetooth.sh</summary>

```setup-jack-bluetooth.sh
#!/bin/bash
# Complete Audio Setup Script
# Removes PipeWire, installs JACK + PulseAudio, configures for HifiBerry + Bluetooth

echo "=== Complete Audio System Setup ==="
echo "This script will:"
echo "  1. Remove PipeWire completely"
echo "  2. Install JACK and PulseAudio"
echo "  3. Configure for HifiBerry DAC + Bluetooth"
echo "  4. Disable auto-start conflicts"
echo ""

# Confirmation
read -p "Continue with complete audio system setup? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    echo "Setup cancelled."
    exit 0
fi

echo ""
echo "Starting setup..."

# 1. Remove PipeWire completely
echo ""
echo "Step 1: Removing PipeWire..."

# Stop PipeWire services first
systemctl --user stop pipewire pipewire-pulse wireplumber 2>/dev/null || true
systemctl --user disable pipewire pipewire-pulse wireplumber 2>/dev/null || true
sudo systemctl stop pipewire pipewire-pulse wireplumber 2>/dev/null || true
sudo systemctl disable pipewire pipewire-pulse wireplumber 2>/dev/null || true

# Remove PipeWire packages
echo "  Removing PipeWire packages..."
sudo apt remove --purge -y pipewire pipewire-pulse pipewire-alsa pipewire-jack wireplumber libpipewire-0.3-0 pipewire-audio-client-libraries 2>/dev/null || true

# Clean up PipeWire configuration
echo "  Removing PipeWire configuration..."
sudo rm -rf /etc/pipewire 2>/dev/null || true
rm -rf ~/.config/pipewire 2>/dev/null || true

echo "✓ PipeWire removed"

# 2. Update package lists
echo ""
echo "Step 2: Updating package lists..."
sudo apt update

# 3. Install required audio packages
echo ""
echo "Step 3: Installing JACK and PulseAudio..."

# Install core audio packages
sudo apt install -y \
    jackd2 \
    pulseaudio \
    pulseaudio-module-jack \
    pulseaudio-module-bluetooth \
    pulseaudio-utils \
    bluez \
    bluez-tools \
    qjackctl \
    jack-tools \
    bc

echo "✓ Audio packages installed"

# 4. Configure JACK for realtime
echo ""
echo "Step 4: Configuring realtime audio..."

# Add user to audio group
sudo usermod -a -G audio $USER

# Configure realtime limits
echo "  Setting up realtime limits..."
if ! grep -q "@audio" /etc/security/limits.conf; then
    echo "@audio - rtprio 99" | sudo tee -a /etc/security/limits.conf
    echo "@audio - memlock unlimited" | sudo tee -a /etc/security/limits.conf
fi

echo "✓ Realtime configuration completed"

# 5. Configure PulseAudio
echo ""
echo "Step 5: Configuring PulseAudio..."

# Create PulseAudio config directory
mkdir -p ~/.config/pulse

# Disable PulseAudio auto-start initially
echo "autospawn = no" > ~/.config/pulse/client.conf

# Configure system-wide PulseAudio
sudo cp /etc/pulse/client.conf /etc/pulse/client.conf.backup
sudo sed -i 's/; autospawn = yes/autospawn = no/' /etc/pulse/client.conf

# Disable PulseAudio auto-start services
systemctl --user disable pulseaudio.service pulseaudio.socket 2>/dev/null || true
systemctl --user mask pulseaudio.service pulseaudio.socket 2>/dev/null || true

# Configure PulseAudio daemon settings
sudo cp /etc/pulse/daemon.conf /etc/pulse/daemon.conf.backup

# Update daemon.conf with optimized settings using sed
echo "  Updating daemon.conf settings..."

# Function to update or add configuration line
update_config() {
    local file="$1"
    local key="$2"
    local value="$3"
    
    if grep -q "^${key}" "$file"; then
        # Setting exists, update it
        sudo sed -i "s/^${key}.*/${key} = ${value}/" "$file"
    elif grep -q "^; ${key}" "$file"; then
        # Setting exists but commented, uncomment and update
        sudo sed -i "s/^; ${key}.*/${key} = ${value}/" "$file"
    else
        # Setting doesn't exist, add it
        echo "${key} = ${value}" | sudo tee -a "$file" > /dev/null
    fi
}

# Update daemon.conf settings
update_config "/etc/pulse/daemon.conf" "daemonize" "no"
update_config "/etc/pulse/daemon.conf" "fail" "yes"
update_config "/etc/pulse/daemon.conf" "allow-module-loading" "yes"
update_config "/etc/pulse/daemon.conf" "allow-exit" "yes"
update_config "/etc/pulse/daemon.conf" "high-priority" "yes"
update_config "/etc/pulse/daemon.conf" "nice-level" "-11"
update_config "/etc/pulse/daemon.conf" "realtime-scheduling" "yes"
update_config "/etc/pulse/daemon.conf" "realtime-priority" "5"
update_config "/etc/pulse/daemon.conf" "default-sample-format" "s16le"
update_config "/etc/pulse/daemon.conf" "default-sample-rate" "44100"
update_config "/etc/pulse/daemon.conf" "default-sample-channels" "2"
update_config "/etc/pulse/daemon.conf" "default-fragments" "4"
update_config "/etc/pulse/daemon.conf" "default-fragment-size-msec" "25"
update_config "/etc/pulse/daemon.conf" "resample-method" "speex-float-1"
update_config "/etc/pulse/daemon.conf" "avoid-resampling" "yes"
update_config "/etc/pulse/daemon.conf" "enable-remixing" "no"
update_config "/etc/pulse/daemon.conf" "remixing-produce-lfe" "no"
update_config "/etc/pulse/daemon.conf" "remixing-consume-lfe" "no"
update_config "/etc/pulse/daemon.conf" "enable-shm" "yes"

# Update default.pa for JACK integration (avoid duplicates)
echo "  Updating default.pa for JACK integration..."

# Check if JACK modules are already configured
if ! grep -q "module-jack-sink" /etc/pulse/default.pa; then
    sudo tee -a /etc/pulse/default.pa > /dev/null << 'EOF'

# JACK integration modules (added by setup script)
.ifexists module-jack-sink.so
load-module module-jack-sink sink_name=jack_out channels=2
.endif

.ifexists module-jack-source.so
load-module module-jack-source source_name=jack_in channels=2
.endif

# Set JACK as default when available
.ifexists module-jack-sink.so
set-default-sink jack_out
.endif
EOF
    echo "  ✓ JACK modules added to default.pa"
else
    echo "  ✓ JACK modules already configured in default.pa"
fi

echo "✓ PulseAudio configured"

# 6. Configure Bluetooth
echo ""
echo "Step 6: Configuring Bluetooth..."

# Enable Bluetooth service
sudo systemctl enable bluetooth
sudo systemctl start bluetooth

# Configure Bluetooth for audio (avoid duplicates)
echo "  Updating Bluetooth configuration..."

# Update or add Bluetooth settings
if ! grep -q "\[General\]" /etc/bluetooth/main.conf; then
    # No [General] section, add it
    sudo tee -a /etc/bluetooth/main.conf > /dev/null << 'EOF'

[General]
Class = 0x200414
DiscoverableTimeout = 0
PairableTimeout = 0
AutoConnectTimeout = 60

[Policy]
AutoEnable = true
EOF
else
    # [General] section exists, update individual settings
    sudo sed -i '/^\[General\]/a Class = 0x200414' /etc/bluetooth/main.conf
    sudo sed -i 's/^#*DiscoverableTimeout.*/DiscoverableTimeout = 0/' /etc/bluetooth/main.conf
    sudo sed -i 's/^#*PairableTimeout.*/PairableTimeout = 0/' /etc/bluetooth/main.conf
    sudo sed -i 's/^#*AutoConnectTimeout.*/AutoConnectTimeout = 60/' /etc/bluetooth/main.conf
    
    # Add Policy section if it doesn't exist
    if ! grep -q "\[Policy\]" /etc/bluetooth/main.conf; then
        echo -e "\n[Policy]\nAutoEnable = true" | sudo tee -a /etc/bluetooth/main.conf > /dev/null
    else
        sudo sed -i 's/^#*AutoEnable.*/AutoEnable = true/' /etc/bluetooth/main.conf
    fi
fi

echo "✓ Bluetooth configured"

# 7. Configure HifiBerry (if not already done)
echo ""
echo "Step 7: Configuring HifiBerry DAC..."

# Check if HifiBerry overlay is enabled
if ! grep -q "dtoverlay=hifiberry-dac" /boot/config.txt; then
    echo "  Adding HifiBerry overlay to /boot/config.txt..."
    
    # Backup config.txt
    sudo cp /boot/config.txt /boot/config.txt.backup
    
    # Add HifiBerry configuration
    sudo tee -a /boot/config.txt > /dev/null << 'EOF'

# HifiBerry DAC configuration
dtparam=audio=off
dtoverlay=hifiberry-dac
EOF
    
    echo "✓ HifiBerry overlay added (requires reboot)"
    REBOOT_NEEDED=true
else
    echo "✓ HifiBerry overlay already configured"
fi

# 8. Clean up and optimize
echo ""
echo "Step 8: Cleaning up..."

# Remove conflicting packages
sudo apt autoremove -y

# Ensure audio devices have correct permissions
sudo usermod -a -G audio $USER

echo "✓ Cleanup completed"

# 9. Create convenient control scripts
echo ""
echo "Step 9: Creating audio control scripts..."

# Create start-jack-bluetooth.sh
cat > ~/start-jack-bluetooth.sh << 'EOF'
#!/bin/bash
# Start JACK + Bluetooth Audio System
# Safe startup that preserves running JUCE applications

echo "=== Starting JACK + Bluetooth Audio ==="

# Check current audio status (no killing)
echo "Checking current audio status..."
if sudo fuser /dev/snd/* 2>/dev/null; then
    echo "⚠ Audio devices are currently in use"
    sudo fuser -v /dev/snd/* 2>/dev/null || true
else
    echo "✓ Audio devices are free"
fi

# Auto-detect HifiBerry card
HIFIBERRY_CARD=$(aplay -l | grep "sndrpihifiberry" | head -1 | cut -d: -f1 | cut -d' ' -f2)

if [ -z "$HIFIBERRY_CARD" ]; then
    echo "✗ HifiBerry not found!"
    exit 1
fi

echo "✓ HifiBerry detected as card $HIFIBERRY_CARD"

# Start JACK (preserving user applications)
echo "Starting JACK (44100Hz, 64 samples)..."
jackd -R -P75 -dalsa -dhw:$HIFIBERRY_CARD -r44100 -p64 -n3 &
sleep 5

if pgrep jackd >/dev/null; then
    echo "✓ JACK started successfully"
    
    if command -v jack_lsp >/dev/null; then
        echo "JACK ports:"
        jack_lsp
    fi
    
    # Start PulseAudio if not running
    if ! pgrep pulseaudio >/dev/null; then
        echo "Starting PulseAudio..."
        pulseaudio --start
        sleep 2
    else
        echo "✓ PulseAudio already running"
    fi
    
    # Load JACK modules
    echo "Loading JACK modules..."
    pactl load-module module-jack-sink sink_name=jack_out channels=2 >/dev/null 2>&1
    pactl set-default-sink jack_out 2>/dev/null
    
    # Configure Bluetooth
    echo "Configuring Bluetooth..."
    bluetoothctl power on >/dev/null 2>&1
    bluetoothctl discoverable on >/dev/null 2>&1
    bluetoothctl pairable on >/dev/null 2>&1
    
    echo ""
    echo "✓ Audio system ready!"
    echo "  JACK: 44100Hz, 64 samples"
    echo "  Bluetooth: Ready for connections"
    echo "  JUCE apps: Use JACK audio driver"
    
else
    echo "✗ JACK failed with 64 samples, trying 128..."
    jackd -R -P75 -dalsa -dhw:$HIFIBERRY_CARD -r44100 -p128 -n3 &
    sleep 3
    
    if pgrep jackd >/dev/null; then
        echo "✓ JACK started with 128 samples (~2.9ms latency)"
    else
        echo "✗ JACK failed completely"
        echo "Manual resolution needed - check audio device usage"
    fi
fi
EOF

chmod +x ~/start-jack-bluetooth.sh

# Create stop-jack-bluetooth.sh
cat > ~/stop-jack-bluetooth.sh << 'EOF'
#!/bin/bash
# Stop JACK + Bluetooth Audio System
# Safely stops audio services and resets Bluetooth

echo "=== Stopping JACK + Bluetooth Audio ==="

# Stop JACK server
echo "Stopping JACK server..."
if pgrep jackd >/dev/null; then
    sudo pkill -TERM jackd
    sleep 2
    
    if pgrep jackd >/dev/null; then
        echo "  Force stopping JACK..."
        sudo pkill -9 jackd
        sleep 1
    fi
    
    echo "✓ JACK server stopped"
else
    echo "✓ JACK server was not running"
fi

# Clean up PulseAudio JACK modules
echo "Cleaning up PulseAudio..."
if pgrep pulseaudio >/dev/null; then
    echo "  Unloading JACK modules..."
    pactl unload-module module-jack-sink 2>/dev/null || true
    pactl unload-module module-jack-source 2>/dev/null || true
    
    echo "  Stopping PulseAudio..."
    pulseaudio -k
    sleep 2
    
    if pgrep pulseaudio >/dev/null; then
        sudo pkill -9 pulseaudio
    fi
    
    echo "✓ PulseAudio stopped"
else
    echo "✓ PulseAudio was not running"
fi

# Reset Bluetooth
echo "Resetting Bluetooth..."
bluetoothctl discoverable off >/dev/null 2>&1
bluetoothctl pairable off >/dev/null 2>&1

# Disconnect audio devices
CONNECTED_DEVICES=$(bluetoothctl devices Connected 2>/dev/null | cut -d' ' -f2)
if [ ! -z "$CONNECTED_DEVICES" ]; then
    echo "  Disconnecting Bluetooth audio devices..."
    for device in $CONNECTED_DEVICES; do
        bluetoothctl disconnect $device >/dev/null 2>&1
    done
fi

echo "✓ Bluetooth reset"

# Show final status
echo ""
echo "=== Cleanup Complete ==="
echo "Audio processes:"
ps aux | grep -E "(jack|pulse)" | grep -v grep | head -3 || echo "  No audio processes running"

echo ""
echo "Audio devices:"
sudo fuser /dev/snd/* 2>/dev/null && echo "  Still in use" || echo "  Free"

echo ""
echo "System ready for restart or different audio configuration"
EOF

chmod +x ~/stop-jack-bluetooth.sh

echo "✓ Created ~/start-jack-bluetooth.sh"
echo "✓ Created ~/stop-jack-bluetooth.sh"

# 10. Final status
echo ""
echo "=== Setup Complete ==="
echo ""
echo "✓ PipeWire removed completely"
echo "✓ JACK and PulseAudio installed and configured"
echo "✓ Bluetooth audio support enabled"
echo "✓ HifiBerry DAC configured"
echo "✓ Realtime audio permissions set"
echo "✓ Auto-start conflicts disabled"
echo ""

if [ "$REBOOT_NEEDED" = true ]; then
    echo "⚠ REBOOT REQUIRED for HifiBerry configuration to take effect"
    echo ""
fi

echo "Next steps:"
echo "1. Reboot the system: sudo reboot"
echo "2. After reboot, run: ./setup-jack-bluetooth.sh"
echo "3. Your JUCE synth should work with JACK audio"
echo "4. Bluetooth devices can connect for audio playback"
echo ""
echo "Files created/modified:"
echo "  ~/start-audio.sh                 - Audio startup script"
echo "  ~/.config/pulse/client.conf      - PulseAudio client config"
echo "  /etc/pulse/daemon.conf           - PulseAudio daemon config"
echo "  /etc/pulse/default.pa            - PulseAudio modules"
echo "  /etc/bluetooth/main.conf         - Bluetooth configuration"
echo "  /etc/security/limits.conf        - Realtime limits"
echo "  /boot/config.txt                 - HifiBerry overlay"
echo ""
echo "Backup files created with .backup extension"
echo ""
echo "Setup completed successfully! 🎵"
```
</details>

## 概要

このガイドでは、Raspberry Pi + HifiBerry DACを使用して、以下の機能を持つプロフェッショナルなオーディオシステムを構築する方法を説明します：

- **低レイテンシJACKオーディオサーバー** (1.5ms@64samples, 44100Hz)
- **Bluetoothオーディオレシーバー機能**
- **JUCEアプリケーション対応** (シンセサイザー、DAW等)
- **PulseAudioとの統合** (システムオーディオとの共存)

## システム構成

### ハードウェア要件
- Raspberry Pi 4 (推奨) または Pi Zero 2
- HifiBerry DAC (PCM5102Aボード)
- Bluetoothアダプター (内蔵または外付け)

### ソフトウェア構成
- **オーディオサーバー**: JACK2 (低レイテンシ・プロオーディオ用)
- **システムオーディオ**: PulseAudio (JACK連携モード)
- **Bluetooth**: BlueZ (A2DPプロファイル対応)
- **削除対象**: PipeWire (競合回避のため完全削除)

## セットアップスクリプトの機能

### `setup-jack-bluetooth.sh` - システム初期設定

#### 1. PipeWire完全削除
```bash
# 以下を実行:
- PipeWireサービス停止・無効化
- 関連パッケージ完全削除
- 設定ファイル削除
```

**理由**: PipeWireとJACK/PulseAudioの競合を完全に回避

#### 2. 必要パッケージインストール
```bash
# インストールされるパッケージ:
- jackd2                    # JACKオーディオサーバー
- pulseaudio                # システムオーディオ
- pulseaudio-module-jack    # JACK連携モジュール
- pulseaudio-module-bluetooth # Bluetooth A2DP
- bluez, bluez-tools        # Bluetooth管理
- qjackctl, jack-tools      # JACK GUI・管理ツール
```

#### 3. リアルタイムオーディオ設定
```bash
# 実行される設定:
- ユーザーをaudioグループに追加
- /etc/security/limits.conf でリアルタイム優先度設定
- rtprio 99, memlock unlimited 設定
```

**効果**: 音声処理の優先度を最高レベルに設定し、レイテンシーを最小化

#### 4. PulseAudio最適化設定

**`/etc/pulse/daemon.conf` の最適化項目**:
- **リアルタイム設定**: `realtime-scheduling = yes`, `realtime-priority = 5`
- **サンプル設定**: `default-sample-rate = 44100`, `default-sample-format = s16le`
- **バッファ最適化**: `default-fragments = 4`, `default-fragment-size-msec = 25`
- **リサンプリング**: `resample-method = speex-float-1`, `avoid-resampling = yes`
- **ミキシング**: `enable-remixing = no` (CPU負荷軽減)

**自動起動制御**:
- PulseAudio自動起動を無効化 (`autospawn = no`)
- systemdサービスをマスク
- JACK起動後に手動でPulseAudioを起動する方式

#### 5. JACK連携設定

**`/etc/pulse/default.pa` への追加**:
```bash
# JACK統合モジュール (JACKが動作中のみ読み込み)
.ifexists module-jack-sink.so
load-module module-jack-sink sink_name=jack_out channels=2
.endif

.ifexists module-jack-source.so  
load-module module-jack-source source_name=jack_in channels=2
.endif

# JACKを優先sink に設定
.ifexists module-jack-sink.so
set-default-sink jack_out
.endif
```

#### 6. Bluetooth最適化

**`/etc/bluetooth/main.conf` 設定**:
```ini
[General]
Class = 0x200414           # オーディオデバイスとして認識
DiscoverableTimeout = 0    # 常時発見可能
PairableTimeout = 0        # 常時ペアリング可能
AutoConnectTimeout = 60    # 自動再接続

[Policy]
AutoEnable = true          # Bluetooth自動有効化
```

#### 7. HifiBerry DAC設定

**`/boot/config.txt` への追加**:
```ini
dtparam=audio=off          # オンボードオーディオ無効化
dtoverlay=hifiberry-dac    # HifiBerry DAC有効化
```

**効果**: HifiBerryが確実にcard 0として認識される

### `start-jack-bluetooth.sh` - 音声システム起動

#### 安全な起動プロセス
1. **現在の音声デバイス使用状況確認** (killは一切行わない)
2. **HifiBerryカード番号自動検出**
3. **JACK起動** (44100Hz, 64samples, 1.5msレイテンシー)
4. **失敗時の自動フォールバック** (128samplesで再試行)
5. **PulseAudio起動** (既に動作中の場合はスキップ)
6. **JACK-PulseAudio連携設定**
7. **Bluetooth設定** (discoverable, pairable)

#### 特徴
- **JUCEアプリケーション保護**: 動作中のアプリケーションを停止しない
- **冪等性**: 何度実行しても安全
- **エラーハンドリング**: 各段階で状況を確認・報告

### `stop-jack-bluetooth.sh` - 音声システム停止

#### 安全な停止プロセス
1. **JACK graceful停止** (SIGTERM → 必要時SIGKILL)
2. **PulseAudio JACKモジュールアンロード**
3. **PulseAudio停止**
4. **Bluetooth状態リセット** (non-discoverable, 接続デバイス切断)
5. **最終状態確認・報告**

## 使用方法

### 初回セットアップ
```bash
# 1. セットアップスクリプト実行
chmod +x complete-audio-setup.sh
./complete-audio-setup.sh

# 2. システム再起動 (HifiBerry設定反映のため)
sudo reboot
```

### 日常的な使用
```bash
# 音声システム開始
~/start-jack-bluetooth.sh

# 音声システム停止  
~/stop-jack-bluetooth.sh
```

## 対応アプリケーション

### JUCE アプリケーション
- オーディオデバイス設定で「JACK」を選択
- 44100Hz, 64samples (1.5ms) または 128samples (2.9ms) で動作
- リアルタイム演奏・録音に最適

### Bluetooth オーディオ
- スマートフォン・タブレットからの音楽再生
- A2DPプロファイル対応
- 自動でJACK経由でHifiBerryから出力

### システムアプリケーション
- ブラウザ、動画プレイヤー等のシステム音声
- PulseAudio経由でJACKにルーティング

## トラブルシューティング

### JACK起動失敗時
```bash
# デバイス使用状況確認
sudo fuser -v /dev/snd/*

# 手動JACK起動テスト
jackd -R -P75 -dalsa -dhw:0 -r44100 -p128 -n3
```

### Bluetooth接続問題
```bash
# Bluetooth状態確認
bluetoothctl show

# デバイス再検索
bluetoothctl scan on
```

### オーディオルーティング確認
```bash
# JACK接続状況
jack_lsp -c

# PulseAudio設定
pactl list short sinks
pactl info
```

## 技術的詳細

### レイテンシー計算
```
レイテンシー(ms) = バッファサイズ(samples) × 1000 / サンプルレート(Hz)

例:
- 64 samples @ 44100Hz = 1.45ms
- 128 samples @ 44100Hz = 2.90ms  
- 256 samples @ 44100Hz = 5.80ms
```

### システムアーキテクチャ
```
[Bluetoothデバイス] → [BlueZ/PulseAudio] → [JACK] → [HifiBerry DAC]
[JUCEアプリ] → [JACK] → [HifiBerry DAC]
[システム音声] → [PulseAudio] → [JACK] → [HifiBerry DAC]
```

### ファイル変更一覧
- `~/.config/pulse/client.conf` - PulseAudio自動起動制御
- `/etc/pulse/daemon.conf` - PulseAudio動作設定
- `/etc/pulse/default.pa` - PulseAudioモジュール設定
- `/etc/bluetooth/main.conf` - Bluetooth設定
- `/etc/security/limits.conf` - リアルタイム権限
- `/boot/config.txt` - HifiBerry有効化

すべての元ファイルは `.backup` 拡張子でバックアップされます。

## まとめ

このセットアップにより、Raspberry Piが以下の特徴を持つプロフェッショナルオーディオシステムとして動作します：

- **低レイテンシー**: 1.5ms以下での音声処理
- **高い安定性**: リアルタイム優先度による安定動作  
- **柔軟性**: JACK, Bluetooth, システム音声の統合
- **プロ仕様**: JUCE/VST対応、DAW使用可能
- **ユーザーフレンドリー**: 簡単な起動・停止スクリプト

音楽制作、ライブ演奏、オーディオ実験など、様々な用途に対応できる本格的なオーディオシステムが完成します。



----
## ここから先は過去の記事

* Raspberry Pi Zero 2ではブツブツ切れてしまいまともに再生できない（同時に動かしているソフトシンセは問題なく鳴っているのでCPUパワーが足りないということではない）。Pi4ではこの問題は起きない。
* ~~iPhoneから再生した場合に音量のコントロールができない~~←できるようになった。

参考にしたサイト等

https://ifritjp.github.io/documents/singleboard/bluetooth-a2dp-receiver/

https://chiroru.hatenablog.com/entry/2021/01/18/210509

https://wiki.archlinux.jp/index.php/Bluetooth_ヘッドセット

https://wiki.archlinux.jp/index.php/PulseAudio/トラブルシューティング

http://www.hot-linux.org/raspi/179


### 必要パッケージのインストール ###
既に入っているものもあるが念のため。

```
$ sudo apt-get install -y bluez pulseaudio-module-bluetooth python-gobject python-gobject-2 pulseaudio-module-jack
```

### Pulse Audioの設定 ###
```
$ sudo nano /etc/pulse/default.pa
```
末尾に下記を追加。最後の1行はJack経由で鳴らすための設定。

```/etc/pulse/default.pa
load-module module-jack-sink
load-module module-jack-source
set-default-sink jack_out
```

### Bluetoothの設定 ###
```
$ bluetoothctl show
Controller XX:XX:XX:XX:XX:XX (public)
	Name: XXXXXXXX
	Alias: XXXXXXXX
	Class: 0x000c0000
	Powered: yes
	Discoverable: no
	Pairable: yes
	UUID: Headset AG                (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: Generic Attribute Profile (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: A/V Remote Control        (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: Generic Access Profile    (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: PnP Information           (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: A/V Remote Control Target (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: Audio Source              (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: Audio Sink                (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	UUID: Headset                   (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
	Modalias: usb:xxxxxxxxxxxxxxx
	Discovering: no
```

### ペアリング ###
```
$ bluetoothctl
# power on
# agent on
# default-agent
# discoverable on
```

ここでiPhoneからBluetooth接続を行う。ペアリングの途中で許可するか聞かれるのでyesとタイプして、その後iPhone側でOKして再度聞かれるのでyesとタイプ。これで繋がった。繋がった後はiPhone側で何か再生したらラズパイ側で鳴る。

### 再生の安定性の問題 ###

Pi4では正常に再生されたがPi Zero 2ではブチブチ切れてしまい実用にならなかった。何が原因かは良くわからない。Alsaに直結すると直るらしいが、Jackで鳴らしたいのでなんとも。バッファサイズの調整でかなり改善することがわかった。

```
$sudo nano /etc/pulse/daemon.conf
```

バッファは64サンプルで動かしているので

```
default-sample-rate = 44100
default-fragments = 256
default-fragment-size-msec = 371
```

とか設定するとかなり安定する。ただ、それでもPi Zero 2では厳しい。topで調べるとkworker/u8:5-events_unboundというのが2つCPUを使いまくっているのが気になるのでこれが原因かもしれない。


### 最新のBlueZをビルドしてインストール ###
下記を参考に最新版 (これを書いている時点では5.62) を入れてみたが状況は変わらず。

https://learn.adafruit.com/install-bluez-on-the-raspberry-pi/installation

### 音量の変更 ###

これを走らせておくと、再生側の機器で音量のコントロールするとそれが効くようになる。

https://github.com/BaReinhard/Super-Simple-Raspberry-Pi-Audio-Receiver-Install/blob/master/usr/local/bin/volume-watcher.py

音量コントロールの信号はちゃんときてて、それをPulseAudioのモジュールでは対応できてないのだけど、このプログラムではPulseAudioのMaster Volumeを動かすことで対処してる。Jackに直接流しているシンセの音量は影響を受けないところがいい。