Садо ва намоиши оғоз
Чаро садо ва тасвирро мепайвандем
Намоиши оғози мусиқӣ чанд миқёси вақт дорад: садо навохта мешавад, саҳнаҳо иваз мешаванд, шаклҳо ҳаракат карда, медурахшанд. Агар ҳар қисм вақтро мустақил ҳисоб кунад, баъди таъхирҳо онҳо метавонанд аз ҳам дур шаванд. Миқёси умумии вақт тасвир ва мусиқиро ҳамоҳанг мекунад.
pyglet файлҳои садоро хонда, садоро ба таври математикӣ ҳам сохта метавонад. Дар мисолҳо синтезро истифода мебарем, то мусиқӣ боргирӣ накунем ва аз файлҳои беруна вобаста набошем. Аввал манбаъ ва навозандаро, сипас суръати мусиқӣ, вақти саҳна ва тағйири баландии садоро меомӯзем.
1. Манбаи садо
Манбаъ, ё source, маълумоти садоро медиҳад. pyglet.media.load("music.ogg") одатан файлро қисм-қисм мехонад ва рамзкушоӣ мекунад: ин streaming барои сабтҳои дароз қулай аст. streaming=False маълумоти рамзкушоишударо ба хотира мегузорад; эффекти кӯтоҳро чандин бор, аз ҷумла ҳамзамон, навохтан мумкин аст.
Дастгирии форматҳо аз декодерҳои дастрас вобаста аст. Барои WAV хонандаи дохилӣ ҳаст; форматҳои дигар метавонанд воситаҳои низом ё FFmpeg талаб кунанд. Дар ин мавзӯъ насб кардани чизе лозим нест: synthesis.Sine аз давомнокӣ бо сония ва басомад бо ҳертс оҳанги синусоидалӣ месозад.
import pyglet
pyglet.options["audio"] = ("silent",)
from pyglet.media import synthesis
beep = synthesis.Sine(duration=0.2, frequency=660)
print(beep.duration)
Натиҷа:
0.2
Басомади 660 Hz маънои 660 ларзиш дар сонияро дорад; ин баландии оҳанг аст, на суръати мусиқӣ. Давомнокии манбаъ 0.2 сония аст. Дар мисол пеш аз муроҷиат ба media драйвери silent интихоб шудааст, то санҷиш садо надиҳад. Барои шунидан дар барномаи худ ин танзимро пеш аз воридкунии аввали media гиред.
2. Player навозишро идора мекунад
Навозанда Player навбати манбаъҳо ва ҳолати навозишро нигоҳ медорад. queue манбаъро илова мекунад, play оғоз ва pause муваққатан қатъ мекунад. volume қиматро аз 0.0 то 1.0 мегирад. Ҳолатро бе интизории анҷоми садо месанҷем.
import pyglet
pyglet.options["audio"] = ("silent",)
from pyglet.media import synthesis
player = pyglet.media.Player()
player.queue(synthesis.Sine(duration=1, frequency=440))
player.volume = 0.4
player.play()
print(player.playing, player.volume)
player.pause()
print(player.playing)
player.delete()
Натиҷа:
True 0.4
False
playing мегӯяд, ки навозиш фаъол аст ё не; баъди pause() он дурӯғ аст. delete() захираҳои навозандаро озод мекунад. Манбаи синтезшудаи ин мисол ҷараёни якдафъаина аст; барои навозиши нави мустақил манбаи нав сохтан мумкин аст.
Роҳи кӯтоҳи source.play() фавран навозандаро бармегардонад. Агар баъдтар баландии садоро тағйир додан ё онро қатъ кардан лозим бошад, Player-и баргаштаро нигоҳ доред. Барои навбати дароз Player-и худро созед; next_source() ба манбаи навбатӣ мегузарад, loop=True бошад манбаи ҷориро такрор мекунад, на худкор тамоми мантиқи рӯйхати навозиши шуморо.
3. Суръат ва вақти мусиқӣ
BPM шумораи зарбҳо дар дақиқа аст. Дар дақиқа 60 сония ҳаст, бинобар ин як зарб 60 / bpm сония давом мекунад. BPM ҳар қадар зиёд бошад, фосилаи байни зарбҳо ҳамон қадар кӯтоҳ аст. Дар мисоли навбатӣ як фосила ва давомнокии се зарбро ҳисоб мекунем.
bpm = 90
seconds_per_beat = 60 / bpm
print(f"{seconds_per_beat:.3f}")
print(f"{3 * seconds_per_beat:.3f}")
Натиҷа:
0.667
2.000
Ҳертси оҳангро бо BPM омехта накунед: якум баландии оҳанг ва дуюм ритмро муайян мекунад. Барои аниматсия зери мусиқӣ t-ро аз player.time гирифтан қулай аст, на ҷамъ кардани вақти тахминии кадр. Ин мавқеи навозиш бо сония аст; баъди гузариш ба манбаи дигар миқёси вақт ба ҳамон манбаъ тааллуқ мегирад.
Агар намоиши оғоз чанд манбаъро дар бар гирад, вақти умумиро нигоҳ доред ё давомнокии манбаъҳои анҷомёфтаро ҷамъ кунед. Пас аз pause() қисми тасвирии ба мусиқӣ вобаста ҳам бояд истад; соатҳои алоҳидаи барнома рафтанро идома медиҳанд ва худкор аз ин таваққуф хабар намеёбанд.
4. Вақти умумӣ ва маҳаллии саҳна
Саҳна порчаи намоиши оғоз бо объектҳо ва давомнокии худ аст. Вақти умумӣ аз оғози тамоми намоиш ва вақти маҳаллӣ аз оғози саҳнаи интихобшуда меравад. Барои як саҳна вақти маҳаллӣ бо тарҳи оғози он аз вақти умумӣ ҳосил мешавад.
start, duration = 1.5, 2.0
for t in (1.5, 2.25, 3.5):
local = t - start
print(0 <= local < duration, f"{local:.2f}")
Натиҷа:
True 0.00
True 0.75
False 2.00
Саҳна дар 1.5 оғоз шуда, 2 сония давом мекунад. Фосила оғозро дар бар гирифта, анҷомро хориҷ мекунад: дар 3.5 ин саҳна дигар фаъол нест. Ин қоида ба саҳнаи навбатӣ сарҳади дақиқ медиҳад ва ҳар дуро ҳамзамон нишон намедиҳад. Вақти маҳаллиро ба формулаҳои пешрафти мавзӯи гузашта додан мумкин аст.
Баъд аз саҳнаи охир рафторро пешакӣ интихоб кунед: дар анҷом истодан, равзанаро бастан ё такрор кардан. Ин қоидаи барнома аст, на хосияти худкори Player. Рафтори рӯйхати навозиш баъд аз треки охир ҳам ҳамин тавр интихоб мешавад.
5. Баландии ҳамвори садо ва такрор
Якбора баланд шудани садо нохуш аст. Афзоиши ҳамвор оғозро паст карда, сатҳро тадриҷан мебардорад; пастшавии ҳамвор онро ба охир тадриҷан кам мекунад. Дар зер ҳиссаҳои афзоиш ва пастшавиро барои порчаи ҳаштсониягӣ алоҳида ҳисоб мекунем. Мавқеъҳо дар дохили ҳудуди он интихоб шудаанд.
length, fade = 8, 2
for pos in (0, 1, 4, 7, 8):
attack = min(1, pos / fade)
release = min(1, (length - pos) / fade)
print(f"{attack:.1f} {release:.1f}")
print(10.5 % 8)
Натиҷа:
0.0 1.0
0.5 1.0
1.0 1.0
1.0 0.5
1.0 0.0
2.5
Сутуни аввал дар оғоз ба 1 мерасад, дуюм дар охир то 0 паст мешавад. Инҳо зарбкунандаҳои баландии садо ҳастанд, на тағйири басомади оҳанг. Сатри охир бақияи тақсимро алоҳида нишон медиҳад: мавқеи умумии 10.5 ба 2.5 дар дохили порчаи такроршавандаи дарозияш 8 табдил меёбад. Такрор давомнокии умумии мусбатро талаб мекунад.
Садо дар дохил чӣ гуна кор мекунад
Манбаъ порчаҳои намунаҳои садоро медиҳад, навозанда онҳоро ба драйвери садо месупорад ва дастгоҳ бо миқёси вақти худ менавозад. Давраи барнома рӯйдодҳоро хизмат мерасонад. Ҳисобҳои тӯлонии бандкунанда дар коркардкунандаҳо интерфейс ва хизматрасонии навозишро ба таъхир меандозанд, бинобар ин давраи рӯйдодҳоро бо while True-и беохир иваз накунед.
Барои ҳамоҳангӣ ҳолати тасвирро аз мавқеи ҷории садо ҳисоб кардан фоиданок аст: агар кадр гузарад, кадри навбатӣ фавран лаҳзаи дурустро нишон медиҳад. Гузариш ба треки нав, такрор ва таваққуф бояд миқёси вақти истифодашавандаро мувофиқ тағйир диҳанд. Ин ҳамон кор бо сарҳадҳост, ки дар кадрҳои калидӣ ва саҳнаҳо дида шуд.
Хатоҳои маъмул ва ислоҳи онҳо
bpm / 60-ро давомнокии зарб шуморидан. Ин шумораи зарбҳо дар сония аст, на сония барои зарб. Барои давомнокӣ60 / bpm-ро истифода баред.player.queue(source)беplayer.play(). Манбаъ ба навбат меравад, вале навозиш оғоз намешавад. Навозандаро оғоз кунед.- Барои нисфи баландии садо
player.volume = 50навиштан. Ҳудуди интизорӣ 0.0–1.0 аст.0.5-ро истифода баред. - Ҳангоми
total = 0амали% total-ро истифода бурдан.ZeroDivisionErrorмешавад. Такрор танҳо бо давомнокии умумии мусбат маъно дорад. - Вақти маҳаллии саҳнаро ба вақти умумии
tбаробар гирифтан. Ҳар саҳнаи нав аллакай аз миёнаи аниматсия оғоз мешавад. Вақти оғози онро тарҳ кунед ва қоидаи сарҳадро ошкоро муайян кунед.
Ёддошти кӯтоҳ
| Вазифа | Восита ё қоида |
|---|---|
| Хондани мусиқӣ | pyglet.media.load(path) |
| Бор кардани эффекти кӯтоҳ ба хотира | streaming=False |
| Сохтани оҳанг бе файл | synthesis.Sine(duration=..., frequency=...) |
| Идораи садо | Player: queue, play, pause, delete |
| Мавқеъ ва баландии садо | player.time, player.volume |
| Сония барои зарб | 60 / bpm |
| Вақти дохили саҳна | вақти умумӣ минус оғози саҳна |
| Такрори порча | бақия аз тақсим ба давомнокии мусбати он |
Акнун намоиши оғоз ҳамаи қисмҳоро дорад: геометрия, навсозӣ аз рӯйи вақт, идора, гузаришҳои ҳамвор ва садо. Онҳоро як принсип мепайвандад: ҳолати ошкор ва миқёси вақти фаҳмо.