Index: chrome/test/functional/media/audio_tools.py |
=================================================================== |
--- chrome/test/functional/media/audio_tools.py (revision 261231) |
+++ chrome/test/functional/media/audio_tools.py (working copy) |
@@ -1,168 +0,0 @@ |
-#!/usr/bin/env python |
-# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-# Use of this source code is governed by a BSD-style license that can be |
-# found in the LICENSE file. |
- |
-"""Audio tools for recording and analyzing audio. |
- |
-The audio tools provided here are mainly to: |
-- record playing audio. |
-- remove silence from beginning and end of audio file. |
-- compare audio files using PESQ tool. |
- |
-The tools are supported on Windows and Linux. |
-""" |
- |
-import commands |
-import ctypes |
-import logging |
-import os |
-import re |
-import subprocess |
-import sys |
-import threading |
-import time |
- |
-import pyauto_media |
-import pyauto |
- |
- |
-_TOOLS_PATH = os.path.abspath(os.path.join(pyauto.PyUITest.DataDir(), |
- 'pyauto_private', 'media', 'tools')) |
- |
-WINDOWS = 'win32' in sys.platform |
-if WINDOWS: |
- _PESQ_PATH = os.path.join(_TOOLS_PATH, 'pesq.exe') |
- _SOX_PATH = os.path.join(_TOOLS_PATH, 'sox.exe') |
- _AUDIO_RECORDER = r'SoundRecorder.exe' |
- _FORCE_MIC_VOLUME_MAX_UTIL = os.path.join(_TOOLS_PATH, |
- r'force_mic_volume_max.exe') |
-else: |
- _PESQ_PATH = os.path.join(_TOOLS_PATH, 'pesq') |
- _SOX_PATH = commands.getoutput('which sox') |
- _AUDIO_RECORDER = commands.getoutput('which arecord') |
- _PACMD_PATH = commands.getoutput('which pacmd') |
- |
- |
-class AudioRecorderThread(threading.Thread): |
- """A thread that records audio out of the default audio output.""" |
- |
- def __init__(self, duration, output_file, record_mono=False): |
- threading.Thread.__init__(self) |
- self.error = '' |
- self._duration = duration |
- self._output_file = output_file |
- self._record_mono = record_mono |
- |
- def run(self): |
- """Starts audio recording.""" |
- if WINDOWS: |
- if self._record_mono: |
- logging.error("Mono recording not supported on Windows yet!") |
- |
- duration = time.strftime('%H:%M:%S', time.gmtime(self._duration)) |
- cmd = [_AUDIO_RECORDER, '/FILE', self._output_file, '/DURATION', |
- duration] |
- # This is needed to run SoundRecorder.exe on Win-64 using Python-32 bit. |
- ctypes.windll.kernel32.Wow64DisableWow64FsRedirection( |
- ctypes.byref(ctypes.c_long())) |
- else: |
- num_channels = 1 if self._record_mono else 2 |
- cmd = [_AUDIO_RECORDER, '-d', self._duration, '-f', 'dat', '-c', |
- str(num_channels), self._output_file] |
- |
- cmd = [str(s) for s in cmd] |
- logging.debug('Running command: %s', ' '.join(cmd)) |
- returncode = subprocess.call(cmd, stdout=subprocess.PIPE, |
- stderr=subprocess.PIPE) |
- if returncode != 0: |
- self.error = 'Failed to record audio.' |
- else: |
- logging.debug('Finished recording audio into %s.', self._output_file) |
- |
- |
-def RunPESQ(audio_file_ref, audio_file_test, sample_rate=16000): |
- """Runs PESQ to compare audio test file to a reference audio file. |
- |
- Args: |
- audio_file_ref: The reference audio file used by PESQ. |
- audio_file_test: The audio test file to compare. |
- sample_rate: Sample rate used by PESQ algorithm, possible values are only |
- 8000 or 16000. |
- |
- Returns: |
- A tuple of float values representing PESQ scores of the audio_file_ref and |
- audio_file_test consecutively. |
- """ |
- # Work around a bug in PESQ when the ref file path is > 128 chars. PESQ will |
- # compute an incorrect score then (!), and the relative path to the ref file |
- # should be a lot shorter than the absolute one. |
- audio_file_ref = os.path.relpath(audio_file_ref) |
- cmd = [_PESQ_PATH, '+%d' % sample_rate, audio_file_ref, audio_file_test] |
- logging.debug('Running command: %s', ' '.join(cmd)) |
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
- output, error = p.communicate() |
- if p.returncode != 0: |
- logging.error('Error running pesq: %s\n%s', output, error) |
- # Last line of PESQ output shows the results. Example: |
- # P.862 Prediction (Raw MOS, MOS-LQO): = 4.180 4.319 |
- result = re.search('Prediction.*= (\d{1}\.\d{3})\t(\d{1}\.\d{3})', |
- output) |
- if not result or len(result.groups()) != 2: |
- return None |
- return (float(result.group(1)), float(result.group(2))) |
- |
- |
-def RemoveSilence(input_audio_file, output_audio_file): |
- """Removes silence from beginning and end of the input_audio_file. |
- |
- Args: |
- input_audio_file: The audio file to remove silence from. |
- output_audio_file: The audio file to save the output audio. |
- """ |
- # SOX documentation for silence command: http://sox.sourceforge.net/sox.html |
- # To remove the silence from both beginning and end of the audio file, we call |
- # sox silence command twice: once on normal file and again on its reverse, |
- # then we reverse the final output. |
- # Silence parameters are (in sequence): |
- # ABOVE_PERIODS: The period for which silence occurs. Value 1 is used for |
- # silence at beginning of audio. |
- # DURATION: the amount of time in seconds that non-silence must be detected |
- # before sox stops trimming audio. |
- # THRESHOLD: value used to indicate what sample value is treates as silence. |
- ABOVE_PERIODS = '1' |
- DURATION = '2' |
- THRESHOLD = '5%' |
- |
- cmd = [_SOX_PATH, input_audio_file, output_audio_file, 'silence', |
- ABOVE_PERIODS, DURATION, THRESHOLD, 'reverse', 'silence', |
- ABOVE_PERIODS, DURATION, THRESHOLD, 'reverse'] |
- logging.debug('Running command: %s', ' '.join(cmd)) |
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
- output, error = p.communicate() |
- if p.returncode != 0: |
- logging.error('Error removing silence from audio: %s\n%s', output, error) |
- |
- |
-def ForceMicrophoneVolumeTo100Percent(): |
- if WINDOWS: |
- # The volume max util is implemented in WebRTC in |
- # webrtc/tools/force_mic_volume_max/force_mic_volume_max.cc. |
- if not os.path.exists(_FORCE_MIC_VOLUME_MAX_UTIL): |
- raise Exception('Missing required binary %s.' % |
- _FORCE_MIC_VOLUME_MAX_UTIL) |
- cmd = [_FORCE_MIC_VOLUME_MAX_UTIL] |
- else: |
- # The recording device id is machine-specific. We assume here it is called |
- # Monitor of render (which corresponds to the id render.monitor). You can |
- # list the available recording devices with pacmd list-sources. |
- RECORDING_DEVICE_ID = 'render.monitor' |
- HUNDRED_PERCENT_VOLUME = '65536' |
- cmd = [_PACMD_PATH, 'set-source-volume', RECORDING_DEVICE_ID, |
- HUNDRED_PERCENT_VOLUME] |
- |
- logging.debug('Running command: %s', ' '.join(cmd)) |
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
- output, error = p.communicate() |
- if p.returncode != 0: |
- logging.error('Error forcing mic volume to 100%%: %s\n%s', output, error) |