Управление звуком. Управление звуком с гарнитуры (Android)

  • 08.08.2019

На некоторых сайтах, созданных на основе Flash-технологии, имеется возможность управления звуком. Например, звук можно выключить в процессе проигрывания мультфильма, изменить громкость, а на некоторых сайтах можно даже регулировать звуковой баланс. Сначала рассмотрим общие сведения, а затем перейдем к примеру.
Объект Sound

Для работы со звуком достаточно воспользоваться объектом класса Sound (Звук) и его методами. Сначала определяется объект с помощью следующей конструкции:
Mysound =new Sound О;
Здесь Mysound - имя, назначаемое объекту класса Sound. Теперь можно управлять звуком, присоединяя через точку к имени объекта имена методов и указывая
необходимые параметры. Ниже перечислены основные методы объекта Sound:

  • attachSound ("имя_звука") -присоединяет к мультфильму звуковой файл из библиотеки;
  • getPan () - возвращает последнее значение баланса в интервале от -100 до 100. Левому динамику соответствует отрицательное значение, правому - положительное. Значение 0 представляет равномерное распределение силы звука междудинамиками;
  • getVolume ()- возвращает уровень громкости в интервале от 0 до 100;
  • setPan () - устанавливает баланс между левым и правым динамиком. Значения от -100 до -1 соответствуют большей громкости левого динамика, а от 1 до 100 - правого;
  • setVolume () - устанавливает громкость в интервале от 0 до 100. Значением по умолчанию является 100;
  • start (задержка, количество_повторений) - начинает воспроизведение звукового файла.Необязательные параметры позволяют задать время задержки в секундах и количество повторений воспроизведения;
  • stop () - приостанавливает воспроизведение звукового файла. Параметров нет;

Кроме перечисленных выше, имеется еще один метод объекта Sound - setTransform. Синтаксис его использования другой. Для вызова метода setTransform необходимо указать объект класса Object, связанный с параметрами управления динамиками. После этого создается объект класса Sound, который будет обрабатывать значения этих параметров с помощью метода setTransform. Параметры, о которых идет речь, определяют уровень входного сигнала в процентах (в интервале от-100 до 100):

  • l l-уровень воспроизведения в левом динамике сигнала, поступающего с левого входа;
  • 1 r- уровень воспроизведения в левом динамике сигнала, поступающего с
    правого входа;
  • r r - уровень воспроизведения в правом динамике сигнала, поступающего
    с правого входа;
  • r l- уровень воспроизведения в правом динамике сигнала, поступающего c левого входа.

По умолчанию параметры ll и rr имеют значение 100, а параметры 1r и rl - значение 0. процедура настройки параметров звука с помощью метода setTransform выглядит следующим образом:
Mytransform = ne Object () ;
Mytransform.il = 100;
Mytransform.Ir = 0;
Mytransform.rr = 100;
Mytransform.rl = 0;
MySound = new Sound ();
MySound.setTransform (Mytransform};

Задавая другие комбинации параметров звука, можно получать интересные эффекты.

Пример элемента управления звуком

Теперь рассмотрим пример создания элемента управления звуком. В новом мультфильме определим три слоя. Первый, самый верхний, назовем action, второй - volume и третий - pan . У нас должно получиться, как показано на рисунке:

Рис. 630. Создание слоев action, volume и pan в мультфильме
В слой action поместим такое действие:

zvuk = new Sound();
zvuk.attachSound("zvuk") ;
zvuk.start(0, 999999);

Этим создаётся новый звуковой объект. Присоединяем его из библиотеки с именем zvuk и запускаем с позиции 0, устанавливая количество повторений 99 999 раз (т. е. практически бесконечно). Если сейчас запустить мультфильм, то мы ничего не увидим и не услышим. Чтобы что-нибудь услышать, надо дать звуку имя. Для этого откроем библиотеку и найдем в ней наш звуковой символ. Неважно, как он там сейчас называется. Чтобы назвать звук, следует щелкнуть на его имени правой кнопкой мыши и в контекстном меню выбрать команду Linkage (). В раскрывшемся окне выберем переключатель Export this symbol и зададим имя zvuk . Иначе говоря, сделаем так, как показано на рисунке:

Рис. 632. Задание координат и размеров шкалы громкости звука

Теперь создадим в этом символе новый слой и поместим туда polzunok_MC_volume . Слой с ползунком должен быть выше слоя со шкалой. Поставим ползунок в центре шкалы и назначим ему такое действие:
onClipEvent (enterFrame) {
root.zvuk.setVolume(this. x) ;

Этим мы добьёмся того, что звук будет иметь значение, соответствующее координате х ползунка. Теперь переходим на главную сцену и вставляем туда символ shkala_volume . Вот мы и создали элемент управления громкостью звука.
Теперь организуем балансировку звука между левым и правым динамиками. Для этого создадим символ-кнопку с названием polzunok_pan и нарисуем там ползунок, затем создадим символ типа Movie Clip с именем polzunok_MC_pan поместим туда наш polzunok_pan . Зададим ему действие:
on (press) {
startDrag (this, false, on (release) { stopDrag ();
-100, 0, 100, 0) ;
}

Теперь создадим ещё один символ типа Movie Clip с именем shkala_pan . Нарисуем там нашу шкалу в виде прямоугольника с параметрами, как показано на рисунке:

Рис. 633. Задание координат и размеров шкалы балансировки звука

В этом же символе создадим ещё один слой и поместим его выше текущего. В этом слое расположим ползунок polzunok_MC_pan и зададим для него следующее действие:

OnClipEvent (enterFrame)
(root.zvuk.setPan(this. x) ;

Теперь переходим на главную сцену и вставляем в неё шкалу балансировки звука shkala_pan . Посмотрите мультфильм и попробуйте изменить положение ползунков. Если ошибок нет, то всё будет работать.

Однако у нас нет цифрового отображения громкости и баланса звука. Давайте разработаем и такой сервис. На главную сцену вставим два динамических текстовых поля. Одно для отображения громкости, другое -для баланса. Назовем их vol и pan соответственно. Сначала займёмся полем vol.
Выделим символ shkala_volume и откроем палитру Action для нашего ползунка. Добавим к уже имеющемуся следующий код:
s = new Sound(zvuk);
_root.vol = s.getVolume();
Таким образом, у нас должно получиться следующее:
onClipEvent (enterFrame) {
в Flash
root . zvuk . set Volume (this. _x) ; ^ = new Sound (zvuk) ; root.vol = s . getVolume () ;
}

Теперь пользователь может видеть цифровое значение громкости звука. Займемся организацией цифрового отображения баланса. Для этого перейдем к символу shkala_pan и добавим к его действиям следующий код:
s = new Sound (zvuk) ;
root. pan = s. getPan (); В результате должно получиться: onClipEvent (enterFrame) {
root. zvuk. set Pan (this -_x) ; s = new Sound(zvuk);
root. pan = s.getPan(); }

Теперь пользователь получает сведения относительно баланса звука. Однако когда ползунок переходит на левую часть шкалы, мы видим отрицательные числа. Обычно в подобных программах отображаются положительные числа и буква «L» или «R». Давайте попробуем сделать так же. Для этого в символе shkala_pan в палитре Actions для ползунка немного изменим существующий код. После замены должно получиться:
onClipEvent (enterFrame) (_root . zvuk . setPan (this ._x) ; s = new Sound (zvuk) ;
if (this._x<0) (
_root.pan = - (s .getPan ()) +"Left" ; } else if (this._x>0) { _root.pan = s . getPan () +"Right" ; } else if (this._x = = 0) (_root.pan = s. getPan ();

Здесь мы поставили условие, что если значение координаты х ползунка меньше нуля (т. е. баланс смещается влево), то в поле pan возвращается значение с минусом (отрицательное число с минусом есть положительное число). Кроме того, к Цифровому значению приписывается строка Left . А если баланс смещается вправо, то всё остаётся как есть и ещё приписывается Right . Если же значение координаты х равно нулю, то вообще ничего не приписывается. Теперь мы имеем более привычную форму отображения баланса. Таким же способом можно сделать, чтобы при минимальной громкости выводилось бы, например «OFF» или «Выкл.», а при максимальном значении - «МАХ». Для этого нужно лишь заменить код для ползунка в символе shkala_volume на следующий:
_root . zvuk. set Volume (this. _x) ;
s = new Sound (zvuk) ;
if (this._x == 0) {
root.vol = "Выкл."; Т
else if (this._x == 100) { _root.vol = "MAX"; Т
else { _root.vol = s.getVolume ();

Возможно, путешествуя по безграничным просторам Всемирной паутины, Вы замечали на некоторых Flash-сайтах возможность управления звуком (например, его можно выключить в процессе проигрывания клипа или изменить его громкость, а некоторых сайтах можно даже регулировать его баланс). Если у Вас есть желание и достаточно терпения, давайте попробуем сделать такое управление звуком.
Для того, чтобы создать этот эффект нам понадобится сам звук и собственно программа Flash 5 (именно пятая версия, поскольку пример написан именно в ней).
Создайте новый клип, а в нём три слоя. Первый (здесь и далее слои будут перечисляться сверху вниз т.е. самый верхний - первый, ниже - второй и. т. д.) назовите "action", второй - "vol" и третий - "pan". У Вас должно получиться что-то вроде этого:

В слой "action" поместите такой action:

zvuk = new Sound();
zvuk.attachSound("zvuk");
zvuk.start(0, 999999);
_
Этим Вы создаёте новый звуковой объект, присоединяем его из библиотеки с именем "zvuk" и запускаем с позиции 0 и повторением 99999 раз т.е. практически бесконечно:Если Вы сейчас запустите клип, то ничего не увидите и не услышите. Чтобы Вы могли что-нибудь услышать Ваш звук, надо дать ему имя для этого откройте библиотеку и найдите там Ваш звук. Неважно как он там называется сейчас, это не имеет никакого значения, чтобы реально назвать звук, Вам следует нажать на его имя правой кнопкой мыши и из контекстного меню выбрать пункт "Linkage" в этом окне выберите пункт "Export this symbol" и задайте имя "zvuk". В общем сделайте всё как показано на рисунке.

Теперь если Вы посмотрите клип, то услышите Ваш звук.
Итак, почти половина работы уже сделана, осталось только организовать управление этим звуком. Для решения этой задачи существует множество способов. Мы сделаем по самому, на мой взгляд, распространенному методу, методу "ползунка" т.к. этот метод применяется во многих музыкальных проигрывателях (например, в WinAmp-е).
Создайте новый символ - кнопку и назовите её "polzunok_vol" эта кнопка будет регулятором громкости. Создайте ещё один символ типа Movie Clip, с названием "Polzunok_MC_vol", поместите туда из библиотеки символ "polzunok_vol" и задайте ему такой action:
____________________________
on (press) {
startDrag (this, false, 0, 7, 100, 7);
}
on (release) {
stopDrag ();
}
___

Затем создайте ещё один символ типа Movie Clip и назовите его "shkala_vol" в этом символе нарисуйте прямоугольник, по которому будет ездить наш ползунок. Для правильной работы задайте ему координаты как показано на рисунке

Теперь создайте в этом символе новый слой и поместите туда "polzunok_MC_vol", слой с ползунком должен быть выше слоя со шкалой, поставьте ползунок по центру шкалы и назначьте ему такой action:

onClipEvent (enterFrame) {

}
__________________________________
Этим мы добьёмся того, что звук будет иметь такое же значение эквивалентное значению "Х" ползунка а поскольку он ползает от 0 до 100 вдоль координаты "Х", то значение звука будет соответствующим. Теперь переходите на главную сцену и вставляйте туда символ "shkala_vol". Вот мы и имеем у себя управление громкостью звука.

Теперь организуем балансировку звука между левым и правым динамиками.
Для этого создадим символ - кнопку с названием "polzunok_pan" и нарисуем там ползунок, затем создадим символ Movie Clip с именем "polzunok_MC_pan" и поместим туда наш "polzunok_pan". Зададим ему action:
_____________________________________
on (press) {
startDrag (this, false, -100, 0, 100, 0);
}
on (release) {
stopDrag ();
}
_____________________________________

Теперь создадим ещё один символ - Movie Clip с именем "shkala_pan"
И нарисуем там нашу шкалу в виде прямоугольника с параметрами в точности как показано на рисунке.

В этом же символе создайте ещё один слой и поместите его выше текущего. В этот слой поместите наш ползунок "polzunok_MC_pan" и задайте ему следующий action:
_________________________________

onClipEvent (enterFrame) {
_root.zvuk.setPan(this._x);
}
________________________________

Теперь переходите на главную сцену и вставляйте в неё "shkala_pan".
Посмотрите клип и попробуйте всё потаскать, если всё было сделано правильно, всё будет работать.

Но, как Вы, наверно сами видите, здесь есть небольшие недостатки. Например пользователь не видит цифрового отображения громкости звука или баланса: Давайте предоставим ему такой сервис.

На главную сцену вставьте два динамических текстовых поля. Одно для отображения громкости, другое для баланса. Назовите их "vol" и "pan" соответственно. Сначала займёмся полем "vol".
Переходите в символ "shkala_vol" и там откройте окно action для нашего ползунка и добавьте туда следующий код к уже имеющемуся там коду
_________________________________
s = new Sound(zvuk);
_root.vol = s.getVolume();
________________________________

и того у Вас должно получиться:
___________________________________
onClipEvent (enterFrame) {
_root.zvuk.setVolume(this._x);
s = new Sound(zvuk);
_root.vol = s.getVolume();
}
___________________________________

Теперь пользователь может видеть цифровое значение громкости звука. Передём к организации цифрового отображения баланса. Переходите к символу "shkala_pan" и там добавьте следующий код:
_____________________________________
s = new Sound(zvuk);
_root.pan = s.getPan();
_____________________________________

В итоге должно получиться:
________________________________
onClipEvent (enterFrame) {
_root.zvuk.setPan(this._x);
s = new Sound(zvuk);
_root.pan = s.getPan();
}
_______________________________

Теперь пользователь получает сведения относительно баланса звука. Вот вроде бы и всё, но при просмотре клипа бросается в глаза одна деталь, а именно: кому понравиться, что когда ползунок переходит на левую часть шкалы, мы видим отрицательные числа: Обычно в подобных программах отображаются положительные числа и буква "L" или "R". Давайте попробуем сделать так же. Для этого в символе "shkala_pan" в окне actions для ползунка добавим, точнее лучше заменим существующий код. После замены должно получиться:

__
onClipEvent (enterFrame) {
_root.zvuk.setPan(this._x);
s = new Sound(zvuk);
if (this._x<0) {
_root.pan = -(s.getPan())+"Left";
} else if (this._x>0) {
_root.pan = s.getPan()+"Right";
} else if (this._x = = 0) {
_root.pan = s.getPan();
}
}
_____________________________________________

Немного поясню получившееся. Мы поставили условие, что если значение "Х" ползунка меньше нуля (т.е. баланс смещается влево), то в поле "pan" возвращается значение с минусом (а минус на минус даёт плюс) и помимо этого приписывается строка Left. Ну а если баланс смещается влево, то всё остаётся как есть и ещё приписывается "Right". Ну а если "Х" координата равна нулю, то вообще ничего не приписывается. Теперь мы имеем более привычную форму записи баланса. Таким же способом можно сделать так, чтобы когда громкость была минимальная, выводилось бы, например "OFF" , а при максимальном значении - "MAX". Для этого нужно лишь заменить код у ползунка в символе "shkala_vol" на следующий код:
________________________________________________
onClipEvent (enterFrame) {
_root.zvuk.setVolume(this._x);
s = new Sound(zvuk);
if (this._x == 0) {
_root.vol = "OFF";
} else if (this._x == 100) {
_root.vol = "MAX";
} else {
_root.vol = s.getVolume();
}
}
_____________________________________________

Теперь мы имеем все, что надо для нормального отображения звука и баланса.

Мы рассмотрим:

  • создание звуковых объектов (объектов типа Sound);
  • привязку звуков к таким объектам;
  • управление воспроизведением звука;
  • динамическое изменение параметров звучания (громкость и панорамирование);
  • загрузку в объект Sound внешних.mp3 файлов.

Объект Sound появился в 5-й версии Flash, поэтому все приёмы,
рассмотренные в статье, кроме загрузки внешних.mp3 файлов, могут быть использованы
и в 5-й версии.

Создание звуковых объектов

Начнём. Вы уже наверное догадались, чтобы производить какие-либо
операции со звуком, нужно создать объект типа Sound . Сделать это очень
просто. Существует стандартная конструкция

soundObject = new Sound(target);

где soundObject - это имя создаваемого звукового объекта, а target
- необязательный параметр, указывающий объект типа MovieClip, или уровень. Если
мы хотим, чтобы наш звуковой объект работал только в одном MovieClip-е или на
одном уровне, то мы должны его создавать с указанием данного параметра:

movieSound = new Sound("SomeClip");

MovieSound = new Sound("_root.teddy.mouth");

LevelSound = new Sound("_level1");

Если же планируется использовать объект в любом месте вашей флэшки,
то он создаётся без параметров:

globalSound = new Sound();

Привязка звука к объектам Sound

Объект Sound позволяет вопроизводить звуки, не втавленные непосредственно
в ключевой кадр временной шкалы. Но для этого их надо сначала поместить в библиотеку,
а затем экспортировать для использования в ActionScript.

Для помещения звука в библиотеку достаточно выбрать "File
-> Import to Library...", и в появившемся окне указать имя звукового
файла.

Теперь, когда файл уже находится в библиотеке, выделяем его,

кликаем правой кнопкой мыши на названии звука, и в появившемся
контекстном меню выбираем "Linkage...". Должно появится подобное окошко:

В поле Identifier мы вводим идентификатор (имя) звукового ресурса.
Можно включить галочку "Export in first frame", тогда звук будет загружен
уже в первом кадре мульта, однако, такой способ неприменим при хоть сколько-нибудь
больших звуках, т.к. до начала загрузки 1-го кадра (даже прелоадера не видно!)
мы видим пустое место, появляется ощущение "зависшего клипа". Поэтому
рекомендуется выключать эту галочку, а в кадре где нужна загрузка звука, помещать
его на временную шкалу с параметрами Sync Stop. Тогда звук не будет загружен
до этого кадра и можно спокойно использовать прелоадер.

Далее, чтобы привязать звуковой ресурс к звуковому объекту, нужно
воспользоваться функцией attachSound(idName) , в которой параметр idName
указывает идентификатор звукового ресурса:

mySound = new Sound();

MySound.attachSound("tada");

После этого наш звуковой объект готов к манипуляциям.

Воспроизведение и остановка звуков

Основными действиями, выполняемыми со звуковыми объектами являются,
конечно же, воспроизведение и остановка воспроизведения.

Для того, чтобы воспроизвести звук, используется функция start(offset,
loops)
объекта Sound . Параметр offset , указывает смещение
в секундах, от начала звукового фрагмента, а loops - количество повторений
проигрываемого фрагмента.

Например, если мы хотим проиграть вторую половину 20-тисекундного
фрагмента 3 раза, мы запишем:

someSoundObject.play(10, 3);

Звук начнёт проигрываться с 10-й секунды.

Оба параметра функции start() являются необязательными.
По умолчанию звук проигрывается с самого начала один раз:

someSoundObject.play();

Можно повторить звуковой фрагмент несколько раз с начала, тогда
мы указываем нулевое смещение:

someSoundObject.play(0, 5);

Чтобы остановить проигрывание, используется функция stop(idName) .
Вызванная без параметров, функция останавливает все звуки. Указав параметр idName,
обозначающий идентификатор звука, можно остановить только один специфический
звук:

globalSnd.stop();

SomeSnd.stop("tada");

Динамическое изменение параметров звука

Объект Sound позволяет динамически устанавливать уровень громкости
и баланс (панорамирование) звука. Существуют также функции для получения значения
баланса и громкости.

Для установки громкости звука используется функция setVolume(value) .
Параметр value может принимать значения от 0 (минимальный уровень) до
100 (максимальный уровень). По умолчанию уровень громкости равен 100.

Для установки баланса используется функция setPan(value) .
Здесь параметр value может принимать значения от -100 (весь звук в левом
канале) до 100 (весь звук в правом канале). Значение 0 (оно стоит по умолчанию)
означает, что звук равномерно распределён между обоими каналами.

globalSnd.setVolume(50); // Половинная
громкость

GlobalSnd.setPan(70); // Сместить звук по большей части в правый канал

Можно использовать функции getVolume() и getPan()
для получения текущего значения громкости и баланса соответственно.

currentVolume = someSnd.getVolume();

CurrentPan = someSnd.getPan();

Можно одновременно устанавливать все параметры звука при помощи
функции setTransform() , но мы её в данной статье не рассматриваем.

Можно в цикле вызывать функции setVolume() и setPan() ,
плавно изменяя значение параметра, и тем самым создавать эффекты затухающего,
возрастающего и/или перемещающегося звука.

Во Flash MX появилась возможность загрузки внешних файлов. Для
этого используется функция loadSound(url, stream) объекта Sound .
Первый параметр, url , указывает путь к файлу. Второй, stream ,
является логической (булевой) переменной, определяющий потоковый режим загрузки
звукового файла. Если значение stream равно false , то Flash дождётся
полной загрузки файла, прежде чем его воспроизводить. Если же stream
равен true , то файл может воспроизводиться в потоковом режиме не загрузившись
полностью. Данный режим рекомендуется использовать только на быстрых каналах
связи или при использовании на локальной машине, т.к. потоковое воспроизведение
по нашим каналам Интернет часто приводит к прерыванию воспроизведения длинными
паузами:).

snd1 = new Sound();

Snd1.loadSound("track03.mp3", true);

Snd2 = new Sound();

Snd2.loadSound("http://someserver.com/some_file.mp3", false);

Специально для этого урока я сделал маленький проигрыватель,
который использует подгрузку внешних файлов и позволяет менять громкость и баланс
проигрываемой композиции. Он также позволяет отслеживать сколько процентов запрошенной
композиции загружено. Этот пример можно скачать ( ,
218k), и поэкспериментировать самому.

Внимание! mp3 файлы не включены в архив с примером, поэтому вам
придётся использовать свои, предварительно изменив пути к ним в параметрах компонента
ComboBox.

Надеюсь, данная статья оказалась вам полезной.

Ко мне обратился человек с просьбой написать программу, которая позволила бы управлять компьютерной мышью при помощи голоса. Тогда я и представить себе не мог, что, практически полностью парализованный человек, который даже не может сам повернуть голову, а может лишь разговаривать, способен развить бурную деятельность, помогая себе и другим жить активной жизнью, получать новые знания и навыки, работать и зарабатывать, общаться с другими людьми по всему свету, участвовать в конкурсе социальных проектов.

Позволю себе привести здесь пару ссылок на сайты, автором и/или идейным вдохновителем которых является этот человек – Александр Макарчук из города Борисов, Беларусь:

Для работы на компьютере Александр использовал программу «Vocal Joystick» - разработку студентов Университета штата Вашингтон, выполненную на деньги Национального Научного Фонда (NSF). См. melodi.ee.washington.edu/vj

Не удержался

Кстати, на сайте университета (http://www.washington.edu/) 90% статей именно про деньги. Трудно найти что-нибудь про научную работу. Вот, например, выдержки с первой страницы: «Том, выпускник университета, раньше питался грибами и с трудом платил за квартиру. Теперь он старший менеджер ИТ-компании и кредитует университет», «Большие Данные помогают бездомным», «Компания обязалась заплатить 5 миллионов долларов за новый учебный корпус».

Это одному мне режет глаз?


Программа была сделана в 2005-2009 годах и хорошо работала на Windows XP. В более свежих версиях Windows программа может зависнуть, что неприемлемо для человека, который не может встать со стула и её перезапустить. Поэтому программу нужно было переделать.

Исходных текстов нет, есть только отдельные публикации, приоткрывающие технологии, на которых она основана (MFCC, MLP – читайте об этом во второй части).

По образу и подобию была написана новая программа (месяца за три).

Собственно, посмотреть, как она работает, можно :

Скачать программу и/или посмотреть исходные коды можно .

Никаких особенных действий для установки программы выполнять не надо, просто щёлкаете на ней, да запускаете. Единственное, в некоторых случаях требуется, чтобы она была запущена от имени администратора (например, при работе с виртуальной клавиатурой “Comfort Keys Pro”):

Пожалуй, стоит упомянуть здесь и о других вещах, которые я ранее делал для того, чтобы можно было управлять компьютером без рук.

Если у вас есть возможность поворачивать голову, то хорошей альтернативой eViacam может послужить гироскоп, крепящийся к голове. Вы получите быстрое и точное позиционирование курсора и независимость от освещения.

Если вы можете двигать только зрачками глаз, то можно использовать трекер направления взгляда и программу к нему (могут быть сложности, если вы носите очки).

Часть II. Как это устроено?

Из опубликованных материалов о программе «Vocal Joystick» было известно, что работает она следующим образом:
  1. Нарезка звукового потока на кадры по 25 миллисекунд с перехлёстом по 10 миллисекунд
  2. Получение 13 кепстральных коэффициентов (MFCC) для каждого кадра
  3. Проверка того, что произносится один из 6 запомненных звуков (4 гласных и 2 согласных) при помощи многослойного персептрона (MLP)
  4. Воплощение найденных звуков в движение/щелчки мыши
Первая задача примечательна лишь тем, что для её решения в реальном времени пришлось вводить в программу три дополнительных потока, так как считывание данных с микрофона, обработка звука, проигрывание звука через звуковую карту происходят асинхронно.

Последняя задача просто реализуется при помощи функции SendInput.

Наибольший же интерес, мне кажется, представляют вторая и третья задачи. Итак.

Задача №2. Получение 13 кепстральных коэффициентов

Если кто не в теме – основная проблема узнавания звуков компьютером заключается в следующем: трудно сравнить два звука, так как две непохожие по очертанию звуковые волны могут звучать похоже с точки зрения человеческого восприятия.

И среди тех, кто занимается распознаванием речи, идёт поиск «философского камня» - набора признаков, которые бы однозначно классифицировали звуковую волну.

Из тех признаков, что доступны широкой публике и описаны в учебниках, наибольшее распространение получили так называемые мел-частотные кепстральные коэффициенты (MFCC).

История их такова, что изначально они предназначались совсем для другого, а именно, для подавления эха в сигнале (познавательную статью на эту тему написали уважаемые Оппенгейм и Шафер, да пребудет радость в домах этих благородных мужей. См. A. V. Oppenheim and R.W. Schafer, “From Frequency to Quefrency: A History of the Cepstrum”).

Но человек устроен так, что он склонен использовать то, что ему лучше знакомо. И тем, кто занимался речевыми сигналами, пришло в голову использовать уже готовое компактное представление сигнала в виде MFCC. Оказалось, что, в общем, работает. (Один мой знакомый, специалист по вентиляционным системам, когда я его спросил, как бы сделать дачную беседку, предложил использовать вентиляционные короба. Просто потому, что их он знал лучше других строительных материалов).

Являются ли MFCC хорошим классификатором для звуков? Я бы не сказал. Один и тот же звук, произнесённый мною в разные микрофоны, попадает в разные области пространства MFCC-коэффициентов, а идеальный классификатор нарисовал бы их рядом. Поэтому, в частности, при смене микрофона вы должны заново обучать программу.

Это всего лишь одна из проекций 13-мерного пространства MFCC в 3-мерное, но и на ней видно, что я имею в виду – красные, фиолетовые и синие точки получены от разных микрофонов: (Plantronix, встроенный массив микрофонов, Jabra), но звук произносился один.

Однако, поскольку ничего лучшего я предложить не могу, также воспользуюсь стандартной методикой – вычислением MFCC-коэффициентов.

Чтобы не ошибиться в реализации, в первых версиях программы в качестве основы был использован код из хорошо известной программы CMU Sphinx, точнее, её реализации на языке C, именующейся pocketsphinx, разработанной в Университете Карнеги-Меллона (мир с ними обоими! (с) Хоттабыч).

Исходные коды pocketsphinx открыты, да вот незадача – если вы их используете, то должны в своей программе (как в исходниках, так и в исполняемом модуле) прописать текст, содержащий, в том числе, следующее:

* This work was supported in part by funding from the Defense Advanced * Research Projects Agency and the National Science Foundation of the * United States of America, and the CMU Sphinx Speech Consortium.
Мне это показалось неприемлемым, и пришлось код переписать. Это сказалось на быстродействии программы (в лучшую сторону, кстати, хотя «читабельность» кода несколько пострадала). Во многом благодаря использованию библиотек “Intel Performance Primitives”, но и сам кое-что оптимизировал, вроде MEL-фильтра. Тем не менее, проверка на тестовых данных показала, что получаемые MFCC-коэффициенты полностью аналогичны тем, что получаются при помощи, например, утилиты sphinx_fe.

В программах sphinxbase вычисление MFCC-коэффициентов производится следующими шагами:

Шаг Функция sphinxbase Суть операции
1 fe_pre_emphasis Из текущего отсчёта вычитается большая часть предыдущего отсчета (например, 0.97 от его значения). Примитивный фильтр, отбрасывающий нижние частоты.
2 fe_hamming_window Окно Хемминга – вносит затухание в начале и конце кадра
3 fe_fft_real Быстрое преобразование Фурье
4 fe_spec2magnitude Из обычного спектра получаем спектр мощности, теряя фазу
5 fe_mel_spec Группируем частоты спектра [например, 256 штук] в 40 кучек, используя MEL-шкалу и весовые коэффициенты
6 fe_mel_cep Берём логарифм и применяем DCT2-преобразование к 40 значениям из предыдущего шага.
Оставляем первые 13 значений результата.
Есть несколько вариантов DCT2 (HTK, legacy, классический), отличающихся константой, на которую мы делим полученные коэффициенты, и особой константой для нулевого коэффициента. Можно выбрать любой вариант, сути это не изменит.

В эти шаги ещё вклиниваются функции, которые позволяют отделить сигнал от шума и от тишины, типа fe_track_snr, fe_vad_hangover, но нам они не нужны, и отвлекаться на них не будем.

Были выполнены следующие замены для шагов по получению MFCC-коэффициентов:

Задача №3. Проверка того, что произносится один из 6 запомненных звуков

В программе-оригинале «Vocal Joystick» для классификации использовался многослойный персептрон (MLP) – нейронная сеть без новомодных наворотов.

Давайте посмотрим, насколько оправдано применение нейронной сети здесь.

Вспомним, что делают нейроны в искусственных нейронных сетях.

Если у нейрона N входов, то нейрон делит N-мерное пространство пополам. Рубит гиперплоскостью наотмашь. При этом в одной половине пространства он срабатывает (выдаёт положительный ответ), а в другой – не срабатывает.

Давайте посмотрим на [практически] самый простой вариант – нейрон с двумя входами. Он, естественно, будет делить пополам двумерное пространство.

Пусть на вход подаются значения X1 и X2, которые нейрон умножает на весовые коэффициенты W1 и W2, и добавляет свободный член C.


Итого, на выходе нейрона (обозначим его за Y) получаем:

Y=X1*W1+X2*W2+C

(опустим пока тонкости про сигмоидальные функции)

Считаем, что нейрон срабатывает, когда Y>0. Прямая, заданная уравнением 0=X1*W1+X2*W2+C как раз и делит пространство на часть, где Y>0, и часть, где Y<0.

Проиллюстрируем сказанное конкретными числами.

Пусть W1=1, W2=1, C=-5;

Теперь посмотрим, как нам организовать нейронную сеть, которая бы срабатывала на некоторой области пространства, условно говоря – пятне, и не срабатывала во всех остальных местах.

Из рисунка видно, что для того, чтобы очертить область в двумерном пространстве, нам потребуется по меньшей мере 3 прямых, то есть 3 связанных с ними нейрона.

Эти три нейрона мы объединим вместе при помощи ещё одного слоя, получив многослойную нейронную сеть (MLP).

А если нам нужно, чтобы нейронная сеть срабатывала в двух областях пространства, то потребуется ещё минимум три нейрона (4,5,6 на рисунках):

И тут уж без третьего слоя не обойтись:

А третий слой – это уже почти Deep Learning…

Теперь обратимся за помощью к ещё одному примеру. Пусть наша нейронная сеть должна выдавать положительный ответ на красных точках, и отрицательный – на синих точках.

Если бы меня попросили отрезать прямыми красное от синего, то я бы сделал это как-то так:

Но нейронная сеть априори не знает, сколько прямых (нейронов) ей понадобится. Этот параметр надо задать перед обучением сети. И делает это человек на основе… интуиции или проб и ошибок.

Если мы выберем слишком мало нейронов в первом слое (три, например), то можем получить вот такую нарезку, которая будет давать много ошибок (ошибочная область заштрихована):

Но даже если число нейронов достаточно, в результате тренировки сеть может «не сойтись», то есть достигнуть некоторого стабильного состояния, далёкого от оптимального, когда процент ошибок будет высок. Как вот здесь, верхняя перекладина улеглась на два горба и никуда с них не уйдёт. А под ней большая область, порождающая ошибки:

Снова, возможность таких случаев зависит от начальных условий обучения и последовательности обучения, то есть от случайных факторов:

- Что ты думаешь, доедет то колесо, если б случилось, в Москву или не доедет?
- А ты как думаешь, сойдётся ента нейронная сеть или не сойдётся?

Есть ещё один неприятный момент, связанный с нейронными сетями. Их «забывчивость».

Если начать скармливать сети только синие точки, и перестать скармливать красные, то она может спокойно отхватить себе кусок красной области, переместив туда свои границы:

Если у нейронных сетей столько недостатков, и человек может провести границы гораздо эффективнее нейронной сети, зачем же их тогда вообще использовать?

А есть одна маленькая, но очень существенная деталь.

Я очень хорошо могу отделить красное сердечко от синего фона отрезками прямых в двумерном пространстве.

Я неплохо смогу отделить плоскостями статую Венеры от окружающего её трёхмерного пространства.

Но в четырёхмерном пространстве я не смогу ничего, извините. А в 13-мерном - тем более.

А вот для нейронной сети размерность пространства препятствием не является. Я посмеивался над ней в пространствах малой размерности, но стоило выйти за пределы обыденного, как она меня легко уделала.

Тем не менее вопрос пока открыт – насколько оправдано применение нейронной сети в данной конкретной задаче, учитывая перечисленные выше недостатки нейронных сетей.

Забудем на секунду, что наши MFCC-коэффициенты находятся в 13-мерном пространстве, и представим, что они двумерные, то есть точки на плоскости. Как в этом случае можно было бы отделить один звук от другого?

Пусть MFCC-точки звука 1 имеют среднеквадратическое отклонение R1, что [грубо] означает, что точки, не слишком далеко отклоняющиеся от среднего, наиболее характерные точки, находятся внутри круга с радиусом R1. Точно так же точки, которым мы доверяем у звука 2 находятся внутри круга с радиусом R2.

Внимание, вопрос: где провести прямую, которая лучше всего отделяла бы звук 1 от звука 2?

Напрашивается ответ: посередине между границами кругов. Возражения есть? Возражений нет.
Исправление: В программе эта граница делит отрезок, соединяющий центры кругов в соотношении R1:R2, так правильнее.

И, наконец, не забудем, что где-то в пространстве есть точка, которая является представлением полной тишины в MFCC-пространстве. Нет, это не 13 нулей, как могло бы показаться. Это одна точка, у которой не может быть среднеквадратического отклонения. И прямые, которыми мы отрежем её от наших трёх звуков, можно провести прямо по границам окружностей:

На рисунке ниже каждому звуку соответствует кусок пространства своего цвета, и мы можем всегда сказать, к какому звуку относится та или иная точка пространства (или не относится ни к какому):

Ну, хорошо, а теперь вспомним, что пространство 13-мерное, и то, что было хорошо рисовать на бумаге, теперь оказывается тем, что не укладывается в человеческом мозгу.

Так, да не так. К счастью, в пространстве любой размерности остаются такие понятия, как точка, прямая, [гипер]плоскость, [гипер]сфера.

Мы повторяем все те же действия и в 13-мерном пространстве: находим дисперсию, определяем радиусы [гипер]сфер, соединяем их центры прямой, рубим её [гипер]плоскостью в точке, равно отдалённой от границ [гипер]сфер.

Никакая нейронная сеть не сможет более правильно отделить один звук от другого.

Здесь, правда, следует сделать оговорку. Всё это справедливо, если информация о звуке – это облако точек, отклоняющихся от среднего одинаково во всех направлениях, то есть хорошо вписывающееся в гиперсферу. Если бы это облако было фигурой сложной формы, например, 13-мерной изогнутой сосиской, то все приведённые выше рассуждения были бы не верны. И возможно, при правильном обучении, нейронная сеть смогла бы показать здесь свои сильные стороны.

Но я бы не рисковал. А применил бы, например, наборы нормальных распределений (GMM), (что, кстати и сделано в CMU Sphinx). Всегда приятнее, когда ты понимаешь, какой конкретно алгоритм привёл к получению результата. А не как в нейронной сети: Оракул, на основе своего многочасового варения бульона из данных для тренировки, повелевает вам принять решение, что запрашиваемый звук – это звук №3. (Меня особенно напрягает, когда нейронной сети пытаются доверить управление автомобилем. Как потом в нестандартной ситуации понять, из-за чего машина повернула влево, а не вправо? Всемогущий Нейрон повелел?).

Но наборы нормальных распределений – это уже отдельная большая тема, которая выходит за рамки этой статьи.

Надеюсь, что статья была полезной, и/или заставила ваши мозговые извилины поскрипеть.

Полное описание параметров, а также инструкция по настройке встроенных звуковых карт Realtek. Настройка воспроизведения, записи, 3D звука. Windows Vista/7/8

2012-02-17T18:19

2012-02-17T18:19

Audiophile"s Software

Copyright 2017, Taras Kovrijenko

Полное или частичное копирование текста допускается только с письменного разрешения автора .

Пролог

На этот раз я затрону тему, актуальную, так сказать, для энтузиастов начинающих - т. е., для тех, кто ещё не разжился на дискретную звуковую карту и хочет выжать максимум из интегрированной.

1. Ликбез

Для начала - краткий ликбез. Кто не знает, или не до конца понимает, что такое аппаратный аудиокодек , внимательно ознакомьтесь с соответствующими страницами Википедии:

Прочитали? Отлично! А теперь было бы ещё очень неплохо, если бы вы ознакомились с двумя моими статьями:

Ну вот, теперь можем и начать.

2. Что мы имеем

Итак, в моём распоряжении ОС Windows 7 SP1 Ultimate x64 (описанная в статье настройка подходит для всех ОС, начиная с Vista), встроенный в материнскую плату (ASUS P7H55-V) кодек ALC887 (имеется даташит), подключенные в задние разъемы внешний усилитель и микрофон (зелёное и розовое гнезда соответственно). Обратите внимание, что настраивать мы будем карту для вывода стерео звука по аналоговому интерфейсу.

3. Установка ПО

Прежде всего надо установить драйвера. Конечно, скорее всего ОС Windows уже сама нашла и установила драйвера для звукового устройства, однако для получения доступа ко всему функционалу, а также для душевного спокойствия, установим пакет драйверов непосредственно от Realtek, последнюю версию которого вы можете скачать на соответствующей странице моего сайта. К слову, указанные здесь настройки проверялись на версии драйверов R2.67.

Скачиваем драйвера, производим несложную процедуру установки (запустив HD_Audio/Setup.exe ), перезагружаем компьютер.

После загрузки ОС в системном трее должен появиться коричневый значок динамика:

4. Настройка драйверов

Прежде всего заходим в Панель Управления Windows->Оборудование и звук->Звук и, убедившись, что наши наушники или динамики подключены в зеленое гнездо звуковой карты, отключаем все ненужные устройства, а наше подключённое устройство делаем устройством по умолчанию:

Заодно проделаем тоже самое с устройствами записи:

Теперь дважды кликаем по значку в трее. Если значка нет, ищем его в скрытых значках, если и там нет - заходим в Панель управления->Оборудование и звук->. Так или иначе, должно открыться окно диспетчера:


Здесь сразу задаем конфигурацию динамиков (стерео), задаем наше аналоговое устройство устройством по умолчанию (после чего соответствующая кнопка потухнет), отключаем, если, не дай Бог, включено, объёмное звучание.


По кнопке в виде жёлтой папки можно настроить отключение определения разъемов передней панели:

Также обратите внимание, что подключённые разъемы отображаются ярким цветом - в нашем случае к зелёному выходу подключены динамики, к розовому входу - микрофон. Здесь - одна весьма важная деталь: дважды нажав по значку разъема, вы увидите окно с выбором типа подключенного устройства. Важно это потому, что если выбрать «наушники» , то кодек будет использовать специальный дополнительный усилитель (иначе звук в наушниках будет слишком тихим), для подключенных же активных колонок или внешних усилителей следует выбирать «Выход на передние динамики» . Здесь же включается автоматическое всплывание данного окна при подключении устройства в какой-либо из разъёмов карты:

С помощью кнопки «i» можно открыть окно с информацией о версии драйвера, DirectX, аудиоконтроллере и версии кодека, там же включается/выключается отображение значка в системном трее:


Теперь поотключаем эффекты:


Настройки «Поправки на помещение» для стерео конфигурации недоступны, что вобщем-то странно - в той же консоли от THX (которая включена, например, в пакет драйверов Creative X-Fi) можно отрегулировать расстояние и угол направления на динамики относительно вашего расположения, что бывает очень полезно, когда вы не сидите непосредственно перед колонками, или же они расположены относительно вас несимметрично. Ну да ладно, пусть это будет на совести разработчиков.

Последняя вкладка дублирует настройки панели управления (впрочем, большинство настроек из Диспетчера есть и в панели управления):


Здесь можно задать параметры системного микшера - с какой частотой дискретизации и глубиной бит Windows будет микшировать все воспроизводимые звуки. Установим 24 бит, 96 кГц. Почему - расскажу далее.

Так как меня постоянно штурмуют вопросами, как настроить микрофон (что, по моему мнению, должно вызывать минимум непоняток), я всё же остановлюсь на настройке устройств записи. Их настройки, кстати, как и устройств воспроизведения, находятся на отдельных вкладках вверху окна. Начнём со стерео микшера:


Здесь всё элементарно. Данное устройство записывает всё, что вы слышите через динамики, т. е., тот готовый звуковой поток, который Windows передает на звуковую карту. Приводится он к указанному виду (раз микшер работает с частотой дискретизации 96 кГц, то и тут поставим столько же).

Но нашим основным устройством записи является, конечно же, микрофон:

Итак, ставим громкость записи на максимум, а усиление микрофона выключаем (потом, если понадобится, можно включить). Также, очень часто люди жалуются, что у них воспроизводится звук воспринимаемый микрофоном, чтобы этого не было - отключаем воспроизведение. На свой вкус - фильтрация шума , подавление эхо . На вкладке , опять же, задается формат записи:

Учитывая характеристики звукозаписывающего тракта, здесь хватит и стандартного 16 бит/44.1 кГц.

5. Настройка foobar2000

В принципе, проделанной работы хватит, чтобы обеспечить наиболее высокое (для данной карты) качество звучания в любом плеере. Но для настоящих параноиков я приведу настройки foobar2000. Нам понадобится, собственно, сам плеер и несколько плагинов к нему - WASAPI output support и SoX Resampler . Ну или вы можете скачать мою сборку , в которой всё уже имеется.

Итак, в настройках вывода плеера (File->Preferences->Playback->Output) выбираем WASAPI: <наше устройство> , разрядность ставим 24 бит :

При выводе через WASAPI Exclusive обходятся все эффекты звуковой карты (если они включены), а также микшер Windows (для которого мы указывали частоту семплирования).

Теперь перейдём к настройкам DSP:


Тут добавляем в цепочку ресемплер SOund eXchange и Advanced Limiter. В настройках ресемплера ставим частоту 96 кГц.

А вот теперь - почему 96 кГц. Я провел серию экспериментов, и вот что мне удалось выяснить. В режиме «выход на передние динамики», если регулятор громкости установлен более чем на 90%, при воспроизведении тестового сигнала udial (частота дискретизации - 44.1 кГц) слышны сильные искажения. Искажения пропадают, если или понизить громкость, или переключиться на режим наушников, или выполнить передискретизацию аудио до 96 кГц.

О причинах данного явления по имеющимся данным судить трудно, но можно сделать выводы и дважды перестраховаться: всё аудио выводить с частотой дискретизации 96 кГц, а громкость не повышать более чем до 90% .

И пара слов о необходимости настройки foobar2000. В принципе, можно выводить звук на устройство «DS: Первичный звуковой драйвер». В этом случае передискретизация будет выполняться средствами Windows (ресемплер там не самый плохой), к тому же ещё и не будут отключаться все остальные звуки (как при воспроизведении через WASAPI Exclusive). Кроме того, выбрав данное устройство, Windows будет выводить звук на то устройство, которое установлено по умолчанию в панели управления, что бывает удобно (например, при отключении одного из устройств звук автоматически переключается на другое). Так что выбор за вами - удобство, или же уверенность в качестве.

6. Воскрешение трехмерного звука и аппаратного микширования

И конечно же я не забыл про геймеров. Так как в Windows, начиная с Vista, отсутствует доступ к аппаратному микшированию потоков (все операции выполняет Windows, а потом один единственный поток выводится на звуковую карту), то разработчики придумали специальную программу, аналог Creative ALchemy, но для Realtek - 3D SoundBack . Она подключается к аппаратным ресурсам через интерфейс OpenAL, эмулируя для указанных программ Windows эмулирует DirectSound устройство (как в Windows XP), а затем просто выполняет преобразование команд DirectSound (или DirectSound 3D) в команды OpenAL, в итоге - получаем настоящий EAX 2.0 в играх, а также возможность преобразования многоканального аудио в стерео с эффектами окружения.

Для запуска программы откройте папку .../Program Files/Realtek/3D Sound Back Beta0.1 , в свойствах файла 3DSoundBack.exe на вкладке «Совместимость» установите режим совместимости с Windows Vista SP2 :

Теперь запустите этот файл. Чтобы добавить приложение - нажмите Add Game , введите название и адрес папки, в которой содержится исполняемый файл программы. Например:


После добавления не забудьте выделить добавленное приложение и нажать кнопку Enable .

Теперь указанное приложение будет по умолчанию использовать эмулированное DirectSound устройство и получит доступ к аппаратным ресурсам звуковой карты:

Эпилог

Ну вот, очередная грандиозная статья завершена. Кстати, я тут подумал: а ведь по-хорошему, эту статью надо было написать одной из первых... Впрочем, на то время у меня ещё не хватило бы знаний, чтобы всё так вот подробно описать, так что оно может быть и к лучшему.

Если что-то непонятно, остались какие-то вопросы - спрашивайте, комментируйте. Желаю удачи!

Информация от спонсора

ЕвроТехника: сеть магазинов бытовой техники. На сайте http://euro-technika.com.ua/ Вы можете ознакомиться с ассортиментом современных 8-ядерных смартфонов (воспользовавшись удобным каталогом) и здесь же сделать заказ (с доставкой или самовывозом).