条件を1秒間満たし続けたらforから抜けたい
解決済
回答 2
投稿
- 評価 0
- クリップ 0
- VIEW 172
質問内容
python3でpyaudioを用いて、音声を録音するプログラムを制作しています。
録音レベル(変数xmax)がしきい値(変数threshold)を上回ると録音が開始されるようになっているのですが、
録音レベル(変数xmax)がしきい値(変数threshold)を1秒間下回り続けたら(または録音開始後10秒たったら)録音を終了するようにしたいです。
つまり、次のプログラムで、変数xmax < 変数threshold の状態が1秒間続いたらfor構文から抜けるようにしたいのです。
#プログラム抜粋
if xmax > threshold: #録音レベルがしきい値を上回ったら
for i in range(0, int(A)):
data = stream.read(chunk)
all.append(data)
#int(A)は10秒分の長さ(おそらく)
どのように記述すればよいのかわからず困っています。
どうすれば良いのでしょうか?
プログラム全体
# -*- coding: utf-8 -*-
#マイク0番からの入力を受ける。録音し、保存する。
import pyaudio
import sys
import time
import wave
import requests
import os
import json
import numpy as np
def recognize_rec():
chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
CARD = 1 #OUTPUTの指定
DEVICE = 0 #OUTPUTの指定
PATH = '/var/tmp/tmp.wav'
#しきい値。これを超えると録音を開始する。
threshold = 0.15 #しきい値
#サンプリングレート、マイク性能に依存
RATE = 16000
#録音時間の上限
RECORD_SECONDS = 10
#pyaudio
p = pyaudio.PyAudio()
#マイク0番を設定
input_device_index = 0
#マイクからデータ取得
stream = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
frames_per_buffer = chunk)
all = []
A = int(RATE) / int(chunk) * int(RECORD_SECONDS)
print("RATE = " + str(RATE))
print("chunk = " + str(chunk))
print("RECORD_SECONDS = " + str(RECORD_SECONDS))
print("RATE / chunk * RECORD_SECONDS = " + str(A))
print("")
while True:
data = stream.read(chunk)
x = np.frombuffer(data, dtype="int16") / 32768.0
#まずサンプルを取る!
xmax = x.max()
if xmax > threshold: #録音レベルがしきい値を上回ったら
for i in range(0, int(A)): #←抜けたいfor構文!
data = stream.read(chunk)
all.append(data)
data = b''.join(all)
out = wave.open(PATH,'w')
out.setnchannels(1) #mono
out.setsampwidth(2) #16bits
out.setframerate(RATE)
out.writeframes(data)
out.close()
break
#time.sleep(0.5)
stream.close()
p.terminate()
if __name__ == '__main__':
print(recognize_rec())
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
- メールアドレスの認証
メールアドレスの認証
- 質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
n個のchunkで連続して閾値を下回ったら、という条件だと次のように書けると思います。
#録音中断までの時間
STOP_SECONDS = 1 # [sec]
B = int(RATE / chunk * STOP_SECONDS)
if xmax > threshold: #録音レベルがしきい値を上回ったら
n = 0 # 連続して閾値を下回った回数を記録するための変数
for i in range(0, int(A)):
data = stream.read(chunk)
all.append(data)
x = np.frombuffer(data, dtype="int16") / 32768.0
xmax = x.max()
if xmax <= threashold:
# 閾値を下回っていたらincrementする
n += 1
else:
# 閾値を上回ったらリセットする
n = 0
# 中断判定
if n == B:
break
投稿
score 2484
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
-1
条件が成立したら、タイマなり時刻カウントなりを開始させ、1秒経過を検出すればいいです。
経過までに条件が不成立になれば、時刻カウントをリセットする、ということで
投稿
score 12613
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 90.49%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
kei-nextone
2018/07/29 10:31