84

Интересный Python #13: играем "Имперский марш"

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

Для воспроизведения звуков будем использовать модуль winsound из стандартной библиотеки Python. Устанавливать ничего не нужно, он уже идёт в комплекте с интерпретатором.

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


Важно: модуль работает только под Windows. Господа линуксоиды, сегодня вы в пролёте :(


Дальше в посте будет много кода в виде скриншотов. Забрать его в виде текста можно здесь.

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

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


Составим список необходимых нот:

Ключ - это название ноты, а значение - это частота.

Запишем мелодию в виде набора нот.

1/4, 3/16 и прочее - это длительность каждой ноты.

Нам понадобятся 2 функции: одна для воспроизведения конкретной ноты, а вторая - для воспроизведения всей мелодии.

Воспроизводим ноту

Воспроизводим мелодию

Наслаждаемся результатами

Оригинальный темп мелодии - 103 BPM.

Забрать полный код в текстовом виде можно здесь.

Программирование на python

950 постов12K подписчиков

Правила сообщества

Публиковать могут пользователи с любым рейтингом. Однако!


Приветствуется:

• уважение к читателям и авторам

• конструктивность комментариев

• простота и информативность повествования

• тег python2 или python3, если актуально

• код публиковать в виде цитаты, либо ссылкой на специализированный сайт


Не рекомендуется:

• допускать оскорбления и провокации

• распространять вредоносное ПО

• просить решить вашу полноценную задачу за вас

• нарушать правила Пикабу

Вы смотрите срез комментариев. Показать все
2
DELETED
Автор поста оценил этот комментарий

Офигеть! Дайте две!


Каждый раз поражаюсь сколько гитик умеет Питон "из коробки".


Хотя, казалось бы, зачем это ему?

Ну пусть будет, прикольно.


Вопрос появился, но не питоновский.

# Не будем слишком подробно останавливаться

# на механике перевода BPM в миллисекунды

duration = int(value * 4 * 1000 * (60 / bpm))

Реквестирую подробности по поводу длительности.

Ведь если нота целая, то она и длится один такт, то есть 1 Beat, который Per Second, разве не так?

И тогда умножение на 4 вроде бы и не нужно. А так получается мы из четвертных целые делаем?

В музыкальной теории нерюх, прошу понять и простить.


Буду благодарен за разъяснения.

раскрыть ветку (6)
1
Автор поста оценил этот комментарий
Реквестирую подробности по поводу длительности.

Там всё чуть сложнее. Всё музыкальное произведение разделяется на такты, а один из самых распространённых размеров такта - это 4/4. В том числе, в таком размере написан и "Имперский марш":


Соответственно, 1 такт = 4 бита.


Для работы с другими размерами такта нужно модифицировать функцию play_melody, но это и код бы усложнило (+1 аргумент и соответствующая логика в теле), и ненужные вопросы за собой повлекло. Так что решил использовать 4\4 по умолчанию, благо в подавляющем большинстве случаев именно он и используется)

Иллюстрация к комментарию
раскрыть ветку (5)
1
DELETED
Автор поста оценил этот комментарий

Спасибо!

Не уверен, что до конца разобрался.

Это при размере 3/3 в одном такте будет только 3 четвертных ноты?


В любом случае, мой наколеночный тейк с синтезом и "Муркой" здесь: https://www.online-python.com/0EjkBFTZ2p


Надеюсь, не сильно переврал муз. термины.

Паузу обозначил 'R' -- так как оно вроде бы 'rest' называется.


PS: плюсомет отключен администрацией, поэтому поблагодарить могу только словами.

раскрыть ветку (4)
1
DELETED
Автор поста оценил этот комментарий

Пара исправлений:

https://www.online-python.com/GMn6aveDKL

раскрыть ветку (3)
0
Автор поста оценил этот комментарий

Солидно! :)


Кстати, интересно стало: а почему бросаете именно `RuntimeError` в `get_note_frequency()`? Понимаю, что проект игрушечный, но всё же ждал здесь `ValueError`, а оно вот как получилось. Если это не опечатка, а осознанный выбор, то расскажите, пожалуйста, почему так?

раскрыть ветку (2)
1
DELETED
Автор поста оценил этот комментарий

Все просто: я Питон знаю очень плохо, и первое, что приходит в голову -- это RuntimeError.

В какой-то момент вспомнил, что вроде есть более подходящий ValueError, но исправить в остальных местах забыл.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Понял, спасибо)

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества