1. PCMファイルの直接再生
RAW PCMデータを直接再生するには以下のコマンドを使用します:
#!/bin/bash
play -t raw -r 44100 -e signed -b 16 -c 2 audio_data.pcm
play -t raw -r 48000 -e float -b 32 -c 2 ./decoded/output.pcm
2. 開発ライブラリのインストールと設定
必要な開発ライブラリをインストールします:
sudo apt install libjsoncpp-dev
sudo ln -s /usr/include/jsoncpp/json/ /usr/include/json
sudo apt install libcurl4-openssl-dev
sudo ln -s /usr/include/x86_64-linux-gnu/curl /usr/include/curl
sudo apt install libopencv-dev
3. CMakeを用いたFFmpegプロジェクト設定
cmake_minimum_required(VERSION 3.10)
project(media_player)
set(SOURCE_FILES main.cpp)
include_directories("/usr/include/x86_64-linux-gnu")
link_directories("/usr/lib/x86_64-linux-gnu")
add_executable(media_player ${SOURCE_FILES})
target_link_libraries(media_player avutil avcodec avformat swresample)
4. 音声形式変換処理
PCMからWAVへの変換実装:
def convert_pcm_to_wav(input_path, output_path, sample_rate, channels, bit_depth):
with open(input_path, "rb") as pcm_file:
raw_data = pcm_file.read()
with wave.open(output_path, "wb") as wav_file:
wav_file.setnchannels(channels)
wav_file.setsampwidth(bit_depth // 8)
wav_file.setframerate(sample_rate)
wav_file.writeframes(raw_data)
5. 多チャンネル音声からの単一チャンネル抽出
import numpy as np
def extract_single_channel(multi_channel_data, total_channels, target_channel):
reshaped_data = multi_channel_data.reshape(-1, total_channels)
transposed_data = reshaped_data.T
return transposed_data[target_channel]
def extract_channel_from_file(input_file, channels, channel_index, bit_resolution, output_file):
dtype_map = {16: np.int16, 32: np.int32}
audio_data = np.fromfile(input_file, dtype=dtype_map[bit_resolution])
mono_data = extract_single_channel(audio_data, channels, channel_index)
mono_data.tofile(output_file)
6. ALSAオーディオデバイスの設定と制御
import alsaaudio
def initialize_playback_device(device_name, sample_rate=16000, channels=8):
try:
audio_device = alsaaudio.PCM(
type=alsaaudio.PCM_PLAYBACK,
mode=alsaaudio.PCM_NORMAL,
rate=sample_rate,
channels=channels,
format=alsaaudio.PCM_FORMAT_S16_LE,
periodsize=160,
device=f"plughw:{device_name}"
)
return audio_device
except Exception as error:
print(f"ALSA device initialization failed: {error}")
return None
7. WAVファイル再生スレッド実装
import wave
import threading
class AudioPlayer:
def __init__(self):
self.audio_device = None
self.playback_active = False
def play_wav_file(self, file_path, device_name):
def playback_thread():
with wave.open(file_path, 'rb') as audio_file:
frame_rate = audio_file.getframerate()
num_channels = audio_file.getnchannels()
sample_width = audio_file.getsampwidth()
self.audio_device = initialize_playback_device(
device_name, frame_rate, num_channels
)
if not self.audio_device:
return
frame_size = frame_rate // 100
audio_data = audio_file.readframes(frame_size)
while audio_data and self.playback_active:
try:
self.audio_device.write(audio_data)
except alsaaudio.ALSAAudioError as e:
print(f"Playback error: {e}")
break
audio_data = audio_file.readframes(frame_size)
if self.audio_device:
self.audio_device.close()
self.playback_active = True
thread = threading.Thread(target=playback_thread)
thread.start()
8. サブプロセスによる音声再生制御
import subprocess
import time
def play_audio_with_timeout(audio_file, device_spec, timeout_seconds):
env = os.environ.copy()
env['AUDIODEV'] = device_spec
process = subprocess.Popen(
f"play {audio_file}",
shell=True,
env=env
)
time.sleep(timeout_seconds)
process.terminate()
process.wait()
# 端末設定の復元
subprocess.run("stty sane", shell=True)
9. ファイルシステム操作ユーティリティ
import os
def find_directory(base_path, target_dir):
for root, dirs, files in os.walk(base_path):
if target_dir in dirs:
return os.path.join(root, target_dir)
return None
def locate_file(base_path, filename):
for root, dirs, files in os.walk(base_path):
if filename in files:
return os.path.join(root, filename)
return None
10. 依存関係解析
def analyze_dependencies(project_path):
command = f'grep -r "import" {project_path}'
process = os.popen(command)
output_lines = process.readlines()
process.close()
dependencies = set()
for line in output_lines:
if line.strip().startswith('#'):
continue
content = line.split(':', 1)[1].strip()
if 'from' not in content:
imports = content.replace('import', '').strip().split(',')
dependencies.update(imp.strip() for imp in imports)
else:
module = content.split('from')[1].split('import')[0].strip()
dependencies.add(module)
return dependencies