0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Audacity + watchdog で自動テンポチェンジ

0
Last updated at Posted at 2026-04-30

はじめに

録画映像の倍速処理に伴い,音声も再生速度を速くすると,音が高くなってしまう.これを防ぐには,FFT を介してピッチを維持したままテンポを変える必要がある.音声処理ソフトではこのような機能が用意されており,そのようなソフトの一つが Audacity である.

Audacity では,定型処理を自動化するためのスクリプティング機能が用意されているので,これを使って AviUtl ExEdit2 のプラグインで橋渡ししたいところであるが,AviUtl の API には再生時間を変化させる機能は用意されていない.仕方ないので,ファイル出力を介してではあるが,可能な範囲で自動化してみよう.

前提条件

AviUtl ExEdit2 では,WAV ファイル出力が用意されていないので,出力プラグイン を使う.

Audacity はデフォルトでオフの mod-script-pipe を Enable にして再起動しておく.

Python および watchdog をインストールしておく.

スクリプト

audacitypipe.py
import math

class AudacityPipe:
	def __init__(self):
		try:
			self.tofile = open(r'\\.\pipe\ToSrvPipe', 'w')
			self.fromfile = open(r'\\.\pipe\FromSrvPipe', 'rt')
			self.eol = '\r\n\0'
		except FileNotFoundError:
			self.tofile = None
			self.fromfile = None
			raise RuntimeError("Audacity の名前付きパイプが見つかりませんでした.mod-script-pipe を Enable にした Audacity が起動していることを確認してください.")
	
	def __del__(self):
		if self.tofile is not None:
			self.tofile.close()
			self.fromfile.close()
	
	def send_command(self, command):
		self.tofile.write(command+self.eol)
		self.tofile.flush()
	
	def get_response(self):
		result = ''
		line = ''
		while True:
			result += line
			line = self.fromfile.readline()
			if line == '\n' and len(result) > 0:
				break
		return result
	
	def do_command(self, command):
		self.send_command(command)
		return self.get_response()

	# ここより上は Audacity のスクリプト例から,下は自分で必要なものを書いた
		
	def open(self, file):
		self.do_command('Import2: Filename="' + file + '"')
	
	def write(self, file):
		self.do_command('Export2: Filename="' + file + '" NumChannels=2')
	
	def close(self):
		self.do_command('TrackClose:')
	
	# ピッチを維持して rate 倍速.16 < rate なら再帰処理
	def change_tempo(self, rate):
		if 16 < rate:
			r = 1<<math.floor(math.log2(rate)*0.5)
			self.change_tempo(rate/r)
			self.change_tempo(r)
		else:
			self.do_command(f'ChangeTempo: Percentage={(rate-1.0)*100.0} SBSMS=True')
	
	def treble(self, db):
		self.do_command(f'BassAndTreble: Treble={db}')
script.py
import os
import time
import re

from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
import audacitypipe

class WavHandler(FileSystemEventHandler):
	def __init__(self):
		super().__init__()
		self.last_processed = ''
		self.ap = audacitypipe.AudacityPipe()
	
	# 書き込みが完了するまで待機
	def wait_for_written(self, path):
		s = -1
		try:
			s2 = os.path.getsize(path)
		except FileNotFoundError:
			time.sleep(1)
			s2 = os.path.getsize(path)
		while s != s2:
			s = s2
			time.sleep(1)
			s2 = os.path.getsize(path)
	
	def process(self, name, rate):
		path = os.path.abspath(f'{name}_{rate}.wav')
		self.wait_for_written(path)
		self.ap.open(path)
		self.ap.change_tempo(rate)
		self.ap.treble(-5)
		path = os.path.abspath(f'{name}.wav')
		self.ap.write(path)
		self.ap.close()
	
	def on_created(self, event):
		if self.last_processed == event.src_path:
			# 書き込み完了後にも on_created が発火するようなので,
			# 直前のトリガーパスと同じならスキップ
			return
		self.last_processed = event.src_path
		m = re.compile(r'^(.*?)_(\d*)\.wav$').match(event.src_path)
		if m:
			# name_n.wav を n 倍速して name.wav に書き出し
			print(f'New file detected: {event.src_path}')
			self.process(m.group(1), int(m.group(2)))
		else:
			# 倍速処理後のファイル名には _ が含まれないので,こちらを通る
			print(f'New file detected, but ignored: {event.src_path}')

if __name__ == '__main__':
	path = './wav' # 監視フォルダ兼書き出し先
	event_handler = WavHandler()
	observer = Observer()
	observer.schedule(event_handler, path, recursive=False)
	observer.start()
	print(f'Watching folder: {path}...')
	try:
		while True:
			time.sleep(1)
	except KeyboardInterrupt:
		observer.stop()
	observer.join()

以上の2ファイルを用意し,python script.py を実行した状態で,AviUtl ExEdit2 から WAVファイル出力プラグインで ./wavname_n.wav という名前(nは整数)で出力すると,同フォルダに n 倍速された音声が name.wav という名前で出力される.テンポチェンジでは音は高くならないのだが,少しキンキンする感じがするので,トレブルで高音域を -5 dB している.具体的な処理手順等は好みで変えてもいいだろう.

出力先を調整して,かんしくん を併用すれば,出力した音声ファイルをタイムラインに投げ返すこともできるだろう.

おわりに

今回は,Audacity と watchdog を使って,WAV ファイル出力に反応して,自動的にテンポチェンジをするスクリプト例を示した.条件に応じてより堅牢な書き方をしたほうがいい場合もあるかもしれない.処理内容もあくまで例に過ぎないが,自分好みの処理を書く際の参考にはなるだろう.

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?