Перейти к содержимому






Фотография
* * * * * 2 голосов

Sound Card / как сгенерировать простой звук

Написано Fingercomp , в Sound Card, Computronics, Add-ons, Programming in Lua, Tutorials 22 Апрель 2017 · 823 просмотров

sound card звук

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

 

Hey! If you are reading this, please tell Vexatos to document the sound card. The in-game manual page is a meaningless piece of text that explains nothing.
Documentation is written to help others to get an idea of how something works. The sound card is a complex thing that definitely needs a how-to guide to be used in programs.
So if he wants the sound card to be used in programs, he should write the proper documentation with the detailed description of each concept, feature, and component method.
The following is the result of efforts put to understand how the sound card works. It took me several months until I realized how to make a simple beep. How am I supposed to create more complex waves? >_>

 

Ну да ладно.

 

 
Хей! Разбирался я недавно, как работает звуковая карта из CX, и поэтому хочу предоставить результаты своих трудов.
Как и написано сверху, доков нет, автор мода бездействует, везде уныние и отчаяние, поэтому пришлось действовать по-хардкорному. То есть чтением исходников и научнейшим тыком.

 

Итак, есть компьютер со звуковой картой. Нужен звук. Звучит просто, м?

 

 

 

Звуковая карта даёт нам замечательные функции вроде установки ADSR-огибающей, типа волны, шума простого или из LFSR, амплитудной и частотной модуляции. Но мы тут решили заняться простым звуком, поэтому всякие LFSR, AM, FM безжалостно выкидываем. Получаем такой план:

  • Открыть канал.
  • Поставить тип волны.
  • Задать частоту волны.
  • Установить громкость.
  • Обработать.

 

1. Открыть канал
Э, извините, а что за каналы?
...
В звуковой карте звук генерируется с помощью инструкций, которые выполняются друг за другом. Почти все работают с определённым каналом. Если бы канал был один, мы бы смогли играть в один момент времени только одну, условно, ноту. Чтобы параллельно шло сразу несколько звуковых волн, нужно использовать несколько каналов. На каждом можно задать свои тип и частоту волны, громкость, ADSR-огибающую. По умолчанию таких каналов в звуковой карте 8 штук.

 

С каналами всё довольно просто: открытый канал генерирует звук, закрытый канал не генерирует звук (правда, нужно будет здесь кое-что поправить, когда будет изучать ADSR).

 

Открыть канал можно с помощью функции sound.open(channel: number). Закрыть: sound.close(channel: number).

 

2. Поставить тип волны
Всего типов звуковая карта поддерживает пять: шум (noise), меандр (square), синусоида (sine), треугольная (triangle) и пилообразная (sawtooth).

 

Изображение

Waveforms ru [CC BY-SA 3.0 (http://creativecommo...enses/by-sa/3.0) или GFDL (http://www.gnu.org/copyleft/fdl.html)], автор Omegatron (original work)
Kirill Borisenko (Russian translation; see File:Waveforms for Cyrillic Segment.png)
Incnis Mrsi (ultimate work), с Викисклада
Очевидно, что разные типы волн звучат по-разному.

 

Установить тип волны можно с помощью функции sound.setWave(channel: number, type: number). Видно, что тип волны должен быть числом. Соответствующее типу волны число можно получить с помощью таблицы sound.modes. Например, sound.modes.sine или sound.modes.noise.

 

3. Задать частоту волны
Чем больше частота, тем выше звук. Частота 440 Hz соответствует ноте ля в первой октаве. Другие частоты можно найти по табличке на Википедии.

 

Используем функцию sound.setFrequency(channel: number, freq: number).

 

4. Установить громкость
Громкость может быть в пределах от 0 до 1 включительно. Половина максимальной громкости - 0.5. И так далее.

 

Функция: sound.setVolume(channel: number, volume: number).

 

5. Обработать
Чтобы обработать все инструкции, нужно вызвать sound.process(). Но если вы просто возьмёте и вызовете функцию, то ничего не услышите. Дело в том, что, достигнув конца инструкций, звуковая карта прекращает генерировать звук.

 

Поэтому нужно выставить некоторую задержку в конце всех других инструкций, чтобы звуковая карта подождала перед прекращением воспроизведения звука. Для этого служит sound.delay(delay: number). Задержка указывается в миллисекундах. Например, sound.delay(2500). При этом эта функция тоже является инструкцией, поэтому её можно выставить несколько раз. Однако если задержка превышает 5000 (5 секунд), то звуковая карта выдаст ошибку.

 

 

 

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

 

Скопируем сюда оттуда пикчу:

Изображение

И вкратце распишем суть.
Если вы хоть когда-либо слышали музыкальные инструменты, вы могли заметить, что громкость звука со временем меняется. У гитары громкость мгновенно нарастает и постепенно затухает, а у флейты нарастает не сразу, например.
Чтобы очень-очень грубо моделировать эти инструменты, мы используем ADSR.
Attack - это время нарастания громкости звука до максимальной (последняя устанавливается через sound.volume).
Decay - время затухания сигнала сразу после достижения максимальной отметки до следующего параметра.
Sustain - отметка громкости, к которой стремится Decay. Значение 1 - это максимальная громкость звука на канале (установленная с помощью sound.setVolume), 0 - отсутствие звука вовсе.
При достижении отметки Sustain звук остаётся на этом уровне до "отпускания клавиши" (т.е. закрытия канала).
Release - время затухания сигнала после закрытия канала, от отметки Sustain до нуля.

 

Время везде в миллисекундах.

 

Попробуем? Вызываем функцию sound.setADSR(channel: number, attack: number, decay: number, sustain: number, release: number) до пятого шага. Например sound.setADSR(1, 1000, 500, 0.33, 1000).
И замечаем, что громкость меняется со временем. Yay!

 

 

 

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

local sound = require("component").sound

sound.close(1)
sound.close(2)

sound.open(1)
sound.setWave(1, sound.modes.sine)
sound.setFrequency(1, 440)
sound.setVolume(1, 1)
sound.setADSR(1, 1000, 500, 0.33, 1000)

sound.delay(1000)

sound.open(2)
sound.setWave(2, sound.modes.noise)
sound.setFrequency(2, 440)
sound.setVolume(2, 0.6)
sound.setADSR(2, 1, 250, 0, 1)

sound.delay(1500)
sound.process()
К остальному, надеюсь, я ещё вернусь в другой записи. Сначала нужно самому понять, как оно работает в версии для CX.
Поэтому наслаждаться пока приходится только бибикалкой.



  • Totoro, Sharplook, electronic_steve и 7 другим это нравится



Я джва года ждал этот гайд!

Кстати, пилообразный сигнал генерируется и используется в осциллографах для отклонения по оси x. Но это никак жаль в ОС не используется.

Пилообразный везде используется

    • Fingercomp это нравится

Обратные ссылки на эту запись [ URL обратной ссылки ]

Обратных ссылок на эту запись нет

Последние версии

Стабильная: 1.7.1
Последняя: 1.7.1

Искать в моем блоге

Новые комментарии

Январь 2018

В П В С Ч П С
 123456
78910111213
14151617 18 1920
21222324252627
28293031   

Полезные ссылки

Официальный сайт OpenComputers

http://oc.cil.li/

 

Официальный форум OpenComputers

http://oc.cil.li/index.php?/index

 

Репозиторий OpenComputers на ГитХабе

https://github.com/M...s/OpenComputers

 

Последние релизы OpenComputers

https://github.com/M...puters/releases

 

Jenkins-сервер

http://ci.cil.li/job...s-dev-MC1.7.10/
 

Репозиторий OpenPrograms

https://github.com/OpenPrograms

 

Репозиторий моих программ

https://github.com/O...rcomp-Programs/

2 посетителей

0 пользователей, 0 гостей, 0 анонимных


Google (1), Yandex (1)

Последние посетители

  • Фотография
    VGAMER_Tiger
    Вчера, 16:54
  • Фотография
    AtomicScience
    16 янв 2018 - 21:31
  • Фотография
    RockMaks_00
    15 янв 2018 - 10:07
  • Фотография
    DotPack
    15 янв 2018 - 01:04
  • Фотография
    Mirotworex
    14 янв 2018 - 23:46
  • Фотография
    Koteyk0o
    14 янв 2018 - 05:03
  • Фотография
    Totoro
    13 янв 2018 - 16:03
  • Фотография
    HixOff
    11 янв 2018 - 22:49
  • Фотография
    Kartograf
    11 янв 2018 - 17:47
  • Фотография
    MrSnake20_15
    10 янв 2018 - 16:52
  • Фотография
    Belzebub
    10 янв 2018 - 16:12
  • Фотография
    LeshaInc
    10 янв 2018 - 09:24
  • Фотография
    MeXaN1cK
    10 янв 2018 - 00:31
  • Фотография
    Megageorgio
    09 янв 2018 - 22:16
  • Фотография
    IS2511
    09 янв 2018 - 17:50
  • Фотография
    RccHD
    08 янв 2018 - 06:32
  • Фотография
    qwertyMAN
    08 янв 2018 - 03:03
  • Фотография
    Litvinov
    07 янв 2018 - 20:34
  • Фотография
    Sharplook
    07 янв 2018 - 14:50
  • Фотография
    eu_tomat
    06 янв 2018 - 20:11
  • Фотография
    Pa3eP
    06 янв 2018 - 05:32
  • Фотография
    FluttyProger
    05 янв 2018 - 23:45
  • Фотография
    rrr_game
    04 янв 2018 - 21:59
  • Фотография
    MnxCool
    04 янв 2018 - 15:33
  • Фотография
    Appo
    03 янв 2018 - 12:21
  • Фотография
    Bencod
    02 янв 2018 - 19:39
  • Фотография
    Laine_prikol
    02 янв 2018 - 17:39
  • Фотография
    ECS
    31 дек 2017 - 19:25
  • Фотография
    folder
    29 дек 2017 - 16:13
  • Фотография
    JLevi
    29 дек 2017 - 07:55
  • Фотография
    ArtemGP
    28 дек 2017 - 16:39
  • Фотография
    Doob
    27 дек 2017 - 14:40
  • Фотография
    Quant
    27 дек 2017 - 10:30
  • Фотография
    Kid
    26 дек 2017 - 23:51
  • Фотография
    vovaluzancomp
    26 дек 2017 - 20:38
  • Фотография
    Nova
    26 дек 2017 - 15:17
  • Фотография
    Electronix205
    26 дек 2017 - 14:26
  • Фотография
    Vestalfa
    26 дек 2017 - 00:03
  • Фотография
    Arseniy10
    25 дек 2017 - 20:16
  • Фотография
    monkey
    25 дек 2017 - 14:39
  • Фотография
    ivan52945
    25 дек 2017 - 02:53
  • Фотография
    NEO
    24 дек 2017 - 19:12
  • Фотография
    vx13
    24 дек 2017 - 18:07
  • Фотография
    mrGreen
    21 дек 2017 - 17:58
  • Фотография
    DarthWirthe
    20 дек 2017 - 22:07
  • Фотография
    1Ridav
    15 дек 2017 - 17:52
  • Фотография
    electronic_steve
    15 дек 2017 - 17:45
  • Фотография
    serafim
    15 дек 2017 - 14:45
  • Фотография
    Zabqer
    15 дек 2017 - 08:41
  • Фотография
    FelixBanan
    14 дек 2017 - 23:20

Лицензия

Яндекс.Метрика