class csv_dtmf(): def __init__(self): self.my_dtmf = DTMF() def read_scale(self, file_name): # 譜面データを読み込み、配列にして返す scale_data = [] csv_reader = csv.reader(open(file_name+'.csv', 'rb'), delimiter=',', quotechar=',') for row in csv_reader: scale_data.append(row) return scale_data def create_dtmf(self, data): wave_data = '' for d in data: wave_data += self.my_dtmf.create_dtmf(DTMF_AMPLITUDE, d[0], float(d[1])) return wave_data def save_wave(self, wave_data, file_name): self.my_dtmf.save(wave_data, 8000, 16, file_name)
def __init__(self): self.my_dtmf = DTMF()
def __init__(self): # いろいろ設定関連 self.ch = capture_setting['ch'] self.fs = capture_setting['fs'] self.chunk = capture_setting['chunk'] self.data_format = capture_setting['format'] # マイクの利用 self.p = pyaudio.PyAudio() self.apiCnt = self.p.get_host_api_count() # どのマイクが利用可能か? # print('Host API Count: %d' % apiCnt) # for cnt in range(apiCnt): # print(p.get_host_api_info_by_index(cnt)) # input_deveice_index = 1 # マイクの選択(どうせ1しか使えない...) self.stream = self.p.open( format=self.data_format, channels=self.ch, rate=self.fs, input=True, frames_per_buffer=self.chunk) # fftした際の配列のn番目の周波数を配列として取得 fft_freq = np.fft.fftfreq(fftLen, d=self.fs**-1) # ========================= # ピアノとfft結果の対応作成 # ========================= # my_piano = piano(30000) # 考慮する最大周波数 self.my_piano = piano(self.fs/1.5) self.freq_list = [] for li, freq in enumerate(fft_freq): tmp_freq_data = [] # tmp_freq_data['freq'] = freq tmp_freq_data.append(freq) conv_freq = self.my_piano.hz_to_scale(freq) if conv_freq == -1: print('error higher freq: %f' % (freq)) print('pianoを宣言するときに、もっと高い周波数まで考慮するように宣言しよう!') sys.exit(-1) else: # tmp_freq_data['Scale'] = conv_freq[0] # tmp_freq_data['doremi'] = conv_freq[1] tmp_freq_data.append(conv_freq[0]) tmp_freq_data.append(conv_freq[1]) self.freq_list.append(tmp_freq_data) # ========================= # DTMFのサンプルを作成 # ========================= self.my_dtmf = DTMF() # それぞれの音(1~9,#,0,*)に対応するサンプルwave self.wave_list = {} for num in range(0, 10): self.wave_list[str(num)] = self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, str(num), self.chunk / (self.fs*1.3)) self.wave_list['#'] = self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, '#', self.chunk / (self.fs*1.0)) self.wave_list['*'] = self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, '*', self.chunk / (self.fs*1.0)) # 音を鳴らさない = 0[Hz]の音を生成しておく self.wave_list['N'] = self.my_dtmf.createSineWave( DTMF_AMPLITUDE, 0, 0, 8000.0, self.chunk / float(self.fs))
class C_spectrumAnalyzer(): def __init__(self): # いろいろ設定関連 self.ch = capture_setting['ch'] self.fs = capture_setting['fs'] self.chunk = capture_setting['chunk'] self.data_format = capture_setting['format'] # マイクの利用 self.p = pyaudio.PyAudio() self.apiCnt = self.p.get_host_api_count() # どのマイクが利用可能か? # print('Host API Count: %d' % apiCnt) # for cnt in range(apiCnt): # print(p.get_host_api_info_by_index(cnt)) # input_deveice_index = 1 # マイクの選択(どうせ1しか使えない...) self.stream = self.p.open( format=self.data_format, channels=self.ch, rate=self.fs, input=True, frames_per_buffer=self.chunk) # fftした際の配列のn番目の周波数を配列として取得 fft_freq = np.fft.fftfreq(fftLen, d=self.fs**-1) # ========================= # ピアノとfft結果の対応作成 # ========================= # my_piano = piano(30000) # 考慮する最大周波数 self.my_piano = piano(self.fs/1.5) self.freq_list = [] for li, freq in enumerate(fft_freq): tmp_freq_data = [] # tmp_freq_data['freq'] = freq tmp_freq_data.append(freq) conv_freq = self.my_piano.hz_to_scale(freq) if conv_freq == -1: print('error higher freq: %f' % (freq)) print('pianoを宣言するときに、もっと高い周波数まで考慮するように宣言しよう!') sys.exit(-1) else: # tmp_freq_data['Scale'] = conv_freq[0] # tmp_freq_data['doremi'] = conv_freq[1] tmp_freq_data.append(conv_freq[0]) tmp_freq_data.append(conv_freq[1]) self.freq_list.append(tmp_freq_data) # ========================= # DTMFのサンプルを作成 # ========================= self.my_dtmf = DTMF() # それぞれの音(1~9,#,0,*)に対応するサンプルwave self.wave_list = {} for num in range(0, 10): self.wave_list[str(num)] = self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, str(num), self.chunk / (self.fs*1.3)) self.wave_list['#'] = self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, '#', self.chunk / (self.fs*1.0)) self.wave_list['*'] = self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, '*', self.chunk / (self.fs*1.0)) # 音を鳴らさない = 0[Hz]の音を生成しておく self.wave_list['N'] = self.my_dtmf.createSineWave( DTMF_AMPLITUDE, 0, 0, 8000.0, self.chunk / float(self.fs)) def setup_windo(self): # アプリケーション作成 self.app = QtGui.QApplication([]) self.app.quitOnLastWindowClosed() # メインウィンドウ self.mainWindow = QtGui.QMainWindow() self.mainWindow.setWindowTitle('Spectrum Analyzer') # Title self.mainWindow.resize(800, 300) # Size # キャンパス centralWid = QtGui.QWidget() self.mainWindow.setCentralWidget(centralWid) # レイアウト lay = QtGui.QVBoxLayout() centralWid.setLayout(lay) # スペクトル表示用ウィジット specWid = pg.PlotWidget(name='spectrum') self.specItem = specWid.getPlotItem() self.specItem.setMouseEnabled(y=False) # y軸方向に動かせなくする self.specItem.setYRange(0, 1000) self.specItem.setXRange(0, fftLen / 4, padding=0) # デフォで表示する幅をいじれる # Axis # X軸についてのいろいろプロット? specAxis = self.specItem.getAxis('bottom') specAxis.setLabel('Frequency [Hz]') specAxis.setScale(self.fs / 2. / (fftLen / 2 + 1)) hz_interval = 1000 # 配列のn番目と表示する周波数の対応 newXAxis = (arange(int(self.fs / 2 / hz_interval)) + 1) * hz_interval oriXAxis = newXAxis / (self.fs / 2. / (fftLen / 2 + 1)) specAxis.setTicks([zip(oriXAxis, newXAxis)]) # キャンパスにのせる lay.addWidget(specWid) # ウィンドウ表示 self.mainWindow.show() # data: 保存データ(ドレミのデータ), distance: 一つの音のデータ, file_name: ファイル名 def save_score_data(self , score_data, distance, file_name): import csv old_data = '' wave_data = '' writecsv = csv.writer(file(file_name+'.csv', 'w'), lineterminator='\n') print('DTMF音楽作成中...') cnt = 0 for data in score_data: if old_data == data: cnt += 1 else: data_time = distance*cnt print('%s, %f[s]' % (data, data_time)) # 波形を生成 wave_data += self.my_dtmf.create_dtmf( DTMF_AMPLITUDE, data, data_time) writecsv.writerow([data,data_time]) cnt = 1 old_data = data self.my_dtmf.save(wave_data, 8000, 16, file_name+'.wav') print('DTMFに変換したものを %s として保存しました。' % (file_name+'.wav')) def spectrumAnalyzer(self): # FFT する信号の初期化 signal = zeros(fftLen, dtype=float) # Update print('音声入力ループ') sound_data = [] # 適当に5秒間実行して終了 for n in xrange(0, self.fs * 7 / self.chunk): try: # dataは文字列型 data = self.stream.read(self.chunk) except IOError as ex: # よくわからんけど、しばらく実行していると結構な頻度でミスってる if ex[1] != pyaudio.paInputOverflowed: raise data = '\x00' * self.chunk print('errorrrrrrrrrrrrrrrrrr') num_data = fromstring(data, dtype='int16') signal = roll(signal, - self.chunk) signal[- len(num_data):] = num_data fftspec = my_fft(signal) spec = abs(fftspec[1: fftLen / 2 + 1]) * signal_scale # スペクトル # print('Max : %.5f' % freq_list[np.argmax(spec)]) if max(spec) >= 2000 and np.argmax(spec) > 3: print('spec: %s' % str(max(spec))) max_list_num = np.argmax(spec) print('Max : %8.3f , %s, %s' % ( self.freq_list[max_list_num][0], self.my_piano.octa_mark[self.freq_list[max_list_num][1]], self.my_piano.onkai[self.freq_list[max_list_num][2]]) ) sound_data.append(phone_scale[self.freq_list[max_list_num][2]]) else: print('none') sound_data.append('N') self.specItem.plot(spec, clear=True) QtGui.QApplication.processEvents() self.save_score_data(sound_data, self.chunk/float(self.fs), OUTPUT_FILE_NAME) self.stream.close() self.p.terminate()
def __init__(self, *args, **kwargs): self._newCallURL = None self.dtmf = DTMF() self.dtmf.main = self self.debugging = Debugging() ShtoomBaseWindow.__init__(self, *args, **kwargs)
class ShtoomMainWindow(ShtoomBaseWindow, ShtoomBaseUI): sending = False audiosource = None cookie = None _muted = False def __init__(self, *args, **kwargs): self._newCallURL = None self.dtmf = DTMF() self.dtmf.main = self self.debugging = Debugging() ShtoomBaseWindow.__init__(self, *args, **kwargs) def debugMessage(self, message): print message log.msg(message, system="ui") def statusMessage(self, message): self.statusLabel.setText(message) def errorMessage(self, message, exception=None): log.msg("%s: %s" % (_("ERROR"), message), system="ui") def hangupButton_clicked(self): self.app.dropCall(self.cookie) self.callButton.setEnabled(True) self.hangupButton.setEnabled(False) self.cookie = None def register_clicked(self): self.app.register() def callButton_clicked(self): sipURL = str(self.addressComboBox.currentText()).strip() if not sipURL: return self.addressComboBox.setCurrentText(sipURL) self.addressComboBox.insertItem(QString(sipURL)) self._newCallURL = sipURL self.callButton.setEnabled(False) defer = self.app.placeCall(sipURL) defer.addCallbacks(self.callConnected, self.callFailed).addErrback(log.err) def callStarted(self, cookie): print "started", cookie self.cookie = cookie self.hangupButton.setEnabled(True) self.statusMessage(_("Calling...")) def callFailed(self, e, message=None): self.errorMessage("call failed", e.getErrorMessage()) self.statusMessage(_("Call Failed")) self.hangupButton.setEnabled(False) self.callButton.setEnabled(True) self.cookie = None def callConnected(self, cookie): self.hangupButton.setEnabled(True) self.statusMessage(_("Call Connected")) if self._muted: self.app.muteCall(self.cookie) def callDisconnected(self, cookie, message): self.statusMessage("%s: %s" % (_("Call Disconnected"), message)) self.hangupButton.setEnabled(False) self.callButton.setEnabled(True) self.cookie = None def getLogger(self): l = Logger(self.debugging.debuggingTextEdit) return l def editPreferences(self): from prefs import PreferencesDialog self.prefs = PreferencesDialog(self, self.app.getOptions()) self.prefs.show() def preferences_save(self, options): self.app.updateOptions(options) self.prefs.hide() def preferences_discard(self): self.prefs.hide() def incomingCall(self, description, cookie): # XXX not good. Blockage. Argh. from twisted.internet import defer from shtoom.exceptions import CallRejected accept = QMessageBox.information( self, "Shtoom", "Incoming Call: %s\nAnswer?" % description, "Yes", "No", "", 0, 1 ) print "accept is", accept if accept == 0: self.cookie = cookie self.callButton.setEnabled(False) self.addressComboBox.setEnabled(False) return defer.succeed(cookie) else: return defer.fail(CallRejected(cookie)) def muteCheck_stateChanged(self, val): if val: self._muted = True else: self._muted = False if self.cookie is not None: if val: self.app.muteCall(self.cookie) else: self.app.unmuteCall(self.cookie) def startDTMF(self, key): if self.cookie: self.app.startDTMF(self.cookie, key) def stopDTMF(self, key): if self.cookie: self.app.stopDTMF(self.cookie, key) def fileDTMF(self, *args): self.dtmf.show() def fileDebugging(self, *args): self.debugging.show() def _gotAuth(self, res): self._authdialog = None return res def getAuth(self, method, realm): # XXX tofix we should queue auth requests self._authdialog = AuthDialog() d = self._authdialog.getAuth(method, realm) d.addCallback(self._gotAuth) return d def __tr(self, str): return QString(_(str)) def registerButton_clicked(self): self.app.register() def fileExit(self): from twisted.internet import reactor reactor.stop() def helpAbout(self): self.aboutDialog = AboutDialog() self.aboutDialog.show()
class ShtoomMainWindow(ShtoomBaseWindow, ShtoomBaseUI): sending = False audiosource = None cookie = None _muted = False def __init__(self, *args, **kwargs): self._newCallURL = None self.dtmf = DTMF() self.dtmf.main = self self.debugging = Debugging() ShtoomBaseWindow.__init__(self, *args, **kwargs) def debugMessage(self, message): print message log.msg(message, system='ui') def statusMessage(self, message): self.statusLabel.setText(message) def errorMessage(self, message, exception=None): log.msg("%s: %s"%(_('ERROR'), message), system='ui') def hangupButton_clicked(self): self.app.dropCall(self.cookie) self.callButton.setEnabled(True) self.hangupButton.setEnabled(False) self.cookie = None def register_clicked(self): self.app.register() def callButton_clicked(self): sipURL = str(self.addressComboBox.currentText()).strip() if not sipURL: return self.addressComboBox.setCurrentText(sipURL) self.addressComboBox.insertItem(QString(sipURL)) self._newCallURL = sipURL self.callButton.setEnabled(False) defer = self.app.placeCall(sipURL) defer.addCallbacks(self.callConnected, self.callFailed).addErrback(log.err) def callStarted(self, cookie): print "started", cookie self.cookie = cookie self.hangupButton.setEnabled(True) self.statusMessage(_('Calling...')) def callFailed(self, e, message=None): self.errorMessage("call failed", e.getErrorMessage()) self.statusMessage(_('Call Failed')) self.hangupButton.setEnabled(False) self.callButton.setEnabled(True) self.cookie = None def callConnected(self, cookie): self.hangupButton.setEnabled(True) self.statusMessage(_('Call Connected')) if self._muted: self.app.muteCall(self.cookie) def callDisconnected(self, cookie, message): self.statusMessage('%s: %s'%(_('Call Disconnected'), message)) self.hangupButton.setEnabled(False) self.callButton.setEnabled(True) self.cookie = None def getLogger(self): l = Logger(self.debugging.debuggingTextEdit) return l def editPreferences(self): from prefs import PreferencesDialog self.prefs =PreferencesDialog(self, self.app.getOptions()) self.prefs.show() def preferences_save(self, options): self.app.updateOptions(options) self.prefs.hide() def preferences_discard(self): self.prefs.hide() def incomingCall(self, description, cookie): # XXX not good. Blockage. Argh. from twisted.internet import defer from shtoom.exceptions import CallRejected accept = QMessageBox.information(self, 'Shtoom', 'Incoming Call: %s\nAnswer?'%description, 'Yes', 'No', '', 0, 1) print "accept is", accept if accept == 0: self.cookie = cookie self.callButton.setEnabled(False) self.addressComboBox.setEnabled(False) return defer.succeed(cookie) else: return defer.fail(CallRejected(cookie)) def muteCheck_stateChanged(self,val): if val: self._muted = True else: self._muted = False if self.cookie is not None: if val: self.app.muteCall(self.cookie) else: self.app.unmuteCall(self.cookie) def startDTMF(self, key): if self.cookie: self.app.startDTMF(self.cookie, key) def stopDTMF(self, key): if self.cookie: self.app.stopDTMF(self.cookie, key) def fileDTMF(self, *args): self.dtmf.show() def fileDebugging(self, *args): self.debugging.show() def _gotAuth(self, res): self._authdialog = None return res def getAuth(self, method, realm): # XXX tofix we should queue auth requests self._authdialog = AuthDialog() d = self._authdialog.getAuth(method, realm) d.addCallback(self._gotAuth) return d def __tr(self, str): return QString(_(str)) def registerButton_clicked(self): self.app.register() def fileExit(self): from twisted.internet import reactor reactor.stop() def helpAbout(self): self.aboutDialog = AboutDialog() self.aboutDialog.show()