この記事の情報リスト
日々音楽制作や音楽活動をしていると、これまで知らなかったファイル形式でプレビューが届くことがあります。
そんな時に慌てず対応できるように、当アカデミーでしっかりと意味と対策を学びましょう。
本日は .w64
という拡張子の音声ファイルについて取り上げます。
この形式は、通常の .wav
ファイルでは扱いきれない巨大な音声データや64bit対応のプロ用ワークフローに対応するために生まれた、「Wave64」という拡張フォーマットです。
Sonyが開発したこの形式は、ポストプロダクションやハイレゾ編集の現場で使われることもありますが、一般的なDAWやメディアプレイヤーでは再生できないことが多く、扱いに苦労します。
ただし中身は通常の.wav
と同じく、基本的には非圧縮PCM(Pulse Code Modulation)であることを理解しておいてください。
今回は .w64
を .wav
に変換するためのPythonスクリプトを紹介します。
これは、音響や録音を学ぶ上でPythonを活用したい方、オーディオ編集に自動化を取り入れたい方にぴったりの内容です。
ちなみに大量ファイルを一括変換する必要がない場合は、後述します非標準GUIDや変則チャンク配置にも寛容なAudacityが圧倒的に便利ですので参考にしてください。
必要なライブラリ
この変換には ffmpeg-python
を使います。内部的には ffmpeg
コマンドを呼び出して変換処理を行います。
以下のコマンドでインストールしましょう:
pip install ffmpeg-python
brew install ffmpeg # macOSユーザー(Homebrew)
Pythonコード:.w64 → .wav 変換スクリプト
"""
Wave64ファイルからdataチャンク以降のリニアPCMデータを抽出し、
通常のWAVファイルとして保存するスクリプト。
"""
import struct
from pathlib import Path
def convert_wave64_to_wav_raw(input_path, output_path, data_offset, sample_rate=96000, num_channels=2, bit_depth=24):
"""
Sony W64ファイルからdataチャンク以降のPCMを抽出し、WAVに変換。
Parameters:
input_path (str): 入力となる .w64 ファイルのパス
output_path (str): 出力となる .wav ファイルのパス
data_offset (int): PCMデータの開始バイト位置(dataチャンクの直後)
sample_rate (int): サンプリングレート(例:96000)
num_channels (int): チャンネル数(例:2)
bit_depth (int): ビット深度(例:24)
Raises:
Exception: ファイル読み取りエラーなど
"""
bytes_per_sample = bit_depth // 8
block_align = num_channels * bytes_per_sample
byte_rate = sample_rate * block_align
with open(input_path, 'rb') as f:
f.seek(data_offset)
pcm_data = f.read()
data_size = len(pcm_data)
wav_header = b'RIFF'
wav_header += struct.pack('<I', 36 + data_size) # ChunkSize
wav_header += b'WAVE'
wav_header += b'fmt ' # Subchunk1ID
wav_header += struct.pack('<I', 16) # Subchunk1Size (PCM)
wav_header += struct.pack('<H', 1) # AudioFormat = 1 (PCM)
wav_header += struct.pack('<H', num_channels)
wav_header += struct.pack('<I', sample_rate)
wav_header += struct.pack('<I', byte_rate)
wav_header += struct.pack('<H', block_align)
wav_header += struct.pack('<H', bit_depth)
wav_header += b'data'
wav_header += struct.pack('<I', data_size)
with open(output_path, 'wb') as wf:
wf.write(wav_header)
wf.write(pcm_data)
print(f'✅ WAV変換成功: {output_path}')
# 実行例
if __name__ == "__main__":
input_w64 = あなたのパス.w64"
output_wav = "あなたのパス.wav"
# dataチャンクの開始位置を指定(例: 0x4000 = 16384)
# AudacityやHexエディタで確認した場合は正確な位置に変更
data_offset_bytes = 16384 # 仮値、必要に応じて調整
convert_wave64_to_wav_raw(
input_path=input_w64,
output_path=output_wav,
data_offset=data_offset_bytes,
sample_rate=96000,
num_channels=2,
bit_depth=24
)
基本的にffmpegを使えばだいたいのコンバートは完了します。
また、先述の通り中身自体は普通のPCMですので、サンプリングレートなどはしっかりと定義されてており、ffmpeg
で変換する場合、自動的に元のサンプリングレートがそのまま保持されます。
w64ファイルそのものの中身を確認するには
file "ファイルのパス.w64"
ffmpegでチャンク構造などのチェックをするには次を叩きます。
ffmpeg -i "ファイルのパス.w64"
エラーで変換できない方
基本的には以下のコードにて、
"""
指定されたフォルダ内のすべての .w64 ファイルを走査し、
リニアPCMデータを抽出して .wav ファイルに変換する一括処理スクリプト。
"""
import struct
from pathlib import Path
def convert_wave64_to_wav_raw(input_path, output_path, data_offset, sample_rate=96000, num_channels=2, bit_depth=24):
"""
Sony W64ファイルからdataチャンク以降のPCMを抽出し、WAVに変換。
"""
bytes_per_sample = bit_depth // 8
block_align = num_channels * bytes_per_sample
byte_rate = sample_rate * block_align
with open(input_path, 'rb') as f:
f.seek(data_offset)
pcm_data = f.read()
data_size = len(pcm_data)
wav_header = b'RIFF'
wav_header += struct.pack('<I', 36 + data_size)
wav_header += b'WAVE'
wav_header += b'fmt '
wav_header += struct.pack('<I', 16)
wav_header += struct.pack('<H', 1)
wav_header += struct.pack('<H', num_channels)
wav_header += struct.pack('<I', sample_rate)
wav_header += struct.pack('<I', byte_rate)
wav_header += struct.pack('<H', block_align)
wav_header += struct.pack('<H', bit_depth)
wav_header += b'data'
wav_header += struct.pack('<I', data_size)
with open(output_path, 'wb') as wf:
wf.write(wav_header)
wf.write(pcm_data)
print(f'✅ 変換成功: {output_path}')
def batch_convert_folder(input_folder, output_folder, data_offset, sample_rate=96000, num_channels=2, bit_depth=24):
"""
指定フォルダ内のすべての .w64 ファイルを .wav に変換する。
Parameters:
input_folder (str): 入力ディレクトリのパス
output_folder (str): 出力ディレクトリのパス
"""
input_folder = Path(input_folder)
output_folder = Path(output_folder)
output_folder.mkdir(parents=True, exist_ok=True)
for w64_file in input_folder.glob("*.w64"):
output_path = output_folder / (w64_file.stem + ".wav")
try:
convert_wave64_to_wav_raw(
input_path=str(w64_file),
output_path=str(output_path),
data_offset=data_offset,
sample_rate=sample_rate,
num_channels=num_channels,
bit_depth=bit_depth
)
except Exception as e:
print(f"❌ 変換失敗: {w64_file.name} → {e}")
# 実行例
if __name__ == "__main__":
input_dir = "フォルダパス" # .w64ファイルが複数あるディレクトリ
output_dir = "フォルダパス" # 変換後の保存先
# dataチャンク開始オフセット(すべて同じ前提。違う場合は拡張対応が必要)
data_offset_bytes = 16384 # 例: 16KB
batch_convert_folder(
input_folder=input_dir,
output_folder=output_dir,
data_offset=data_offset_bytes,
sample_rate=96000,
num_channels=2,
bit_depth=24
)
一括変換のためにPythonを使います。
ただし当然波形編集ソフトだと簡単に変換できますので、1ファイルだけであるとか、そこまで頻繁に変換する必要はない場合であると、例えば無料のAudacityなどを使えば変換は簡単です。
.w64
はSony独自の GUID(チャンク識別子) を使うケースがあり、これは ffmpeg
や sox
などの一般ツールが「準拠外」として拒否する原因になります。
Audacityは libsndfile
ベースの読み込み処理をしており、非標準GUIDや変則チャンク配置にも寛容です。
また、多くの .w64
ファイルは data
チャンクが深い場所に埋め込まれており、再構築には オフセットの明示が必要ですが、Audacityはこれをすべて内部で自動処理してくれるので、迷った時はAudacityでOK。
Windows版一括変換サンプルコード
"""
指定されたWindowsフォルダ内のすべての .w64 ファイルを走査し、
リニアPCMデータを抽出して .wav ファイルに変換する一括処理スクリプト。
"""
import struct
from pathlib import Path
def convert_wave64_to_wav_raw(input_path, output_path, data_offset, sample_rate=96000, num_channels=2, bit_depth=24):
"""
Sony W64ファイルからdataチャンク以降のPCMを抽出し、WAVに変換。
"""
bytes_per_sample = bit_depth // 8
block_align = num_channels * bytes_per_sample
byte_rate = sample_rate * block_align
with open(input_path, 'rb') as f:
f.seek(data_offset)
pcm_data = f.read()
data_size = len(pcm_data)
wav_header = b'RIFF'
wav_header += struct.pack('<I', 36 + data_size)
wav_header += b'WAVE'
wav_header += b'fmt '
wav_header += struct.pack('<I', 16)
wav_header += struct.pack('<H', 1)
wav_header += struct.pack('<H', num_channels)
wav_header += struct.pack('<I', sample_rate)
wav_header += struct.pack('<I', byte_rate)
wav_header += struct.pack('<H', block_align)
wav_header += struct.pack('<H', bit_depth)
wav_header += b'data'
wav_header += struct.pack('<I', data_size)
with open(output_path, 'wb') as wf:
wf.write(wav_header)
wf.write(pcm_data)
print(f'✅ 変換成功: {output_path}')
def batch_convert_folder(input_folder, output_folder, data_offset, sample_rate=96000, num_channels=2, bit_depth=24):
"""
指定フォルダ内のすべての .w64 ファイルを .wav に変換する(Windows対応)。
"""
input_folder = Path(input_folder)
output_folder = Path(output_folder)
output_folder.mkdir(parents=True, exist_ok=True)
for w64_file in input_folder.glob("*.w64"):
output_path = output_folder / (w64_file.stem + ".wav")
try:
convert_wave64_to_wav_raw(
input_path=str(w64_file),
output_path=str(output_path),
data_offset=data_offset,
sample_rate=sample_rate,
num_channels=num_channels,
bit_depth=bit_depth
)
except Exception as e:
print(f"❌ 変換失敗: {w64_file.name} → {e}")
# 実行例
if __name__ == "__main__":
# Windowsのパス記法。raw文字列または \\ でエスケープ
input_dir = r"C:\Users\YourName\Downloads\w64_files"
output_dir = r"C:\Users\YourName\Desktop\wav_output"
# dataチャンク開始オフセット(バイナリ確認後に設定)
data_offset_bytes = 16384 # 例: 16KB
batch_convert_folder(
input_folder=input_dir,
output_folder=output_dir,
data_offset=data_offset_bytes,
sample_rate=96000,
num_channels=2,
bit_depth=24
)
まとめ:なぜ.w64ファイルにするのか?
一括変換はコピペでOK!
ファイル数が少ない場合はAudacityを推奨!
さいごに、なぜ.w64にするのか?
それは、ファイルサイズの圧縮のためです。
例えば無料の神WindowsDAWアプリといえばCakewalk by BandLab(旧SONAR含む)ですが、録音ファイルの形式設定で .w64
を選べる場合があります。
特に録音時間が非常に長い場合は自動で.w64ファイルに切り替わる設定になっているわけです。
長尺の場合は、残りディスクの節約のため、やはり.w64ファイルにするのが安全策であると言えます。