いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

コナン君の「蝶ネクタイ型変声機」を試す

 この記事に直接関連した内容の書籍をブログ管理人が出版しました。記事をリファインして、極力詳しく解説しています。見ていただけるとうれしいです(2022年5月15日(日))。↓

 ご存じ『名探偵コナン』では主人公のコナン君が天才発明家、阿笠博士の発明した「蝶ネクタイ型変声機」を使い、自由に色んな人の声で推理を披露します。でもぼくはずっと不思議でした。例えばコナン君が毛利探偵の声でしゃべるとき、毛利探偵の声しか聞こえないではありませんか!! 登場人物の誰も疑問には感じていないようです。これに関しては大体のところを過去の記事で書きました。もちろん想像です。
www.omoshiro-suugaku.com
今回、実験してみたのでご紹介します。もちろん人間の声で実験するとなるとリアルタイムに処理しなければならず、ぼくにはハードルが高すぎます。そこで、音楽を使いwavファイル保存する、というふうにしました。
 原理はこんな感じ。毛利探偵の声をA、コナン君の声をBとします。-BはBのデータの符号を一斉に反転したデータです。これも前、このブログで実験していて、Bを聴くのと変わりがありませんでした。
www.omoshiro-suugaku.com
片方のスピーカからはA-Bが、もう片方のスピーカからはBが聞こえるようにデータを作ってやります。A-Bは人間にはA、Bが混ざって聞こえるだけです。2つのスピーカを離して聴くと2曲が聞こえます。しかしスピーカを向かい合わせるとBが聞こえなくなるのです。(A-B)+B = A ということですね。コナン君の変声機は(毛利探偵の声)-(コナン君の声)を出します。これだけ聴くと2人の声がダブって聞こえてしまいますが、ここにコナン君自身の口から出る(コナン君の声)を足し合わせれば(毛利探偵の声)だけが残って目的は達成されるのです!!
 Python で書きました。エラー処理とかは全然やっていませんので、試したい方は各自で注意してください。途中、「//2」(整数の範囲で2で割る)をしている部分があります。これはタイミングによっては2曲のピーク付近同士が重なってオーバーフローする可能性があるので、これを防ぐためです。

#左右に A-B, B を入れたwavファイルを作る
#====================
import sys
import numpy as np
import scipy as sp
from scipy.fftpack import fft
import wave

# A
wavefile = wave.open('14_旅愁.wav',"rb") #こちらの方が長い曲
buf = wavefile.readframes(wavefile.getnframes())#サウンドデータ部分の読み取り
buf = np.frombuffer(buf, dtype= "int16")#16bit符号付き整数に変換
wavefile.close()
print(wavefile.getparams())
sdata = buf.copy()
ldata = sdata[0::2] #左のデータ
rdata = sdata[1::2] #右のデータ

# B
wavefile1 = wave.open('01_さくらさくら.wav',"rb")#こちらの方が短い曲
buf = wavefile1.readframes(wavefile1.getnframes())#サウンドデータ部分の読み取り
buf = np.frombuffer(buf, dtype= "int16")#16bit符号付き整数に変換
wavefile1.close()
print(wavefile1.getparams())
sdata1 = buf.copy()
rdata1 = sdata1[1::2] #右のデータ

#2つの曲(A,B)とも、右のデータだけを使う。
rdata[:rdata1.size] = rdata[:rdata1.size]//2 - rdata1//2 #A-B を入れる
ldata[:rdata1.size] = rdata1//2 #B を入れる
sdata[0::2] = ldata
sdata[1::2] = rdata

writewave = wave.Wave_write("keshitene.wav")
writewave.setparams(wavefile.getparams()) #保存先ファイルにパラメータをセット
writewave.writeframes(sdata) #編集したサウンドデータを保存
writewave.close()
sys.exit()
#====================

 面白かったです。ただ、現実には今回スピーカを向かい合わせるようなことはできませんし、向かい合わせても消えるはずの方の音楽が少し聞こえてしまいます。完全な解決には至っていません。……と言うよりまだ先は長いです。阿笠博士の天才ぶりには舌を巻くばかりです。