· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Все тот же 8253

Посл.отвђт Сообщенiе


Дата: Дек 3, 2003 23:04:06

bsl_zcs проверь пожалуйста мои мысли:
push ds ; всякий случай
mov cx,40h ; начало загрузки адреса
mov ds,cx ; где находится количество
; произошедших импульсов длительностью 55 мс каждый
; и вроде бы с момента включения компа или его сброса?
shr bx,1 ; Вот этого я не понял?
mov dx,[ds:6Ch] ; Не понял что конкретно
wait2: mov cx,[ds:6Ch] ; засылаем?
sub cx,dx ; И о чем конкретно говорит это вычитание?
cmp cx,bx ;
jb wait2
pop ds
Пробывал тот алгоритм с циклом переделать вроде получилось:
wait: mov cx,n
loop1: loop loop1
mov cx,n
loop2: loop cx,loop2
dec bx
jnz wait1
И таких штук до кучи.
Но что ты предложил хотел бы понять бы полностью.
Да кстати по счет длительностей, там не все так просто. Если взять ноту
звучащую 1 секунду, как четверть, то половинной будет 2 сек, целая 4 секунды,
а восьмая 0.5 сек. шестнадцатая 0.25 сек. А ведь вдругой раз мелодия может иметь
более быстрый ритм, поэтому мне 55 мс не очень-то подходит и интересуюсь я
этой ячейкой, только из большого любопытства.
+ P.S.: Че не так настучал по клаве то прими сорри.

240856313__TERMIN.ASM


Дата: Дек 4, 2003 08:02:52

EvilsInterrupt
Но что ты предложил хотел бы понять бы полностью.
Теоретически ячейка 0000:046Ch увеличивается каждые 55 мс на единицу. Почему shr bx,1 не подскажу. В dx сохраняется число тиков до начала цикла, в cx постоянно определяется количество прошедших тиков и сравнивается со значением в bx, которое означает длительность паузы. Алгоритм содержит баг, который проявится, если потребность в паузе возникнет в районе 0000:046Ch == FFFFh.


вдругой раз мелодия может иметь более быстрый ритм, поэтому мне 55 мс не очень-то подходит
55 мс ~ 18 раз в секунду, ты знаешь кого-нибудь, кто сможет воспроизвести на инструменте по одной более 18 нот за одну секунду? В принципе можно заставить таймер тикать вплоть до 1.9*10^6 тиков в секунду, но это надо делать аккуратно.


Дата: Дек 4, 2003 08:41:29

55 мс ~ 18 раз в секунду, ты знаешь кого-нибудь, кто сможет воспроизвести на инструменте по одной более 18 нот за одну секунду?

Витя Зинчук. 20 нот в секунду в "полёте шмеля". Если память не изменяет, обычно играется 10 нот в этом произведении.

Yngwie Malsteen. Тоже умеет ;)


Дата: Дек 4, 2003 10:06:58

xzazet
20 нот в секунду в "полёте шмеля"
Ссылку на партитуру не подскажешь?


Дата: Дек 4, 2003 10:29:42

q_q
Ссылку на партитуру не подскажешь?
google рулит!


Дата: Дек 4, 2003 11:54:16

ssx
google рулит!
Справедливо.
Нашел, например, Cкоростное исполнение “Полета шмеля” Н. Римского-Корсакова.
Тогда поставлю вопрос иначе, много ли есть произведений, в которых автор настаивает на такой скорости для правильного/качественного восприятия?


Дата: Дек 4, 2003 12:35:42

EvilsInterrupt

Пардон за оффтоп


q_q

Если есть произведения, которые должны звучать (по мнению авторов) около 300 лет в предложенном темпе. Думаю, есть и произведения, которые промелькнут за секунду. Их право.


Дата: Дек 4, 2003 21:01:12

В музыке существует несколько десятков темпов исполнения. И различные части одного произведении могут исполняться в разном темпе. Кроме того переход от одного темпа к другому могет быть плавными(в течении нескольких тактов).
Есть еще триоли - когда за время исполнения двух нот исполняются три ноты.
Лучший вариант - повесить свой обработчик на прерывание от таймера, и включать/выключать звук, изменять частоту в момент обработки прерывания. И записывать в счетчик время до следующего события. Только я не помню в каком из 8 режимов прерывание вызывается при переполнении.


Дата: Дек 4, 2003 21:32:58

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

_164339427__termin.asm


Дата: Дек 4, 2003 21:33:53

и второй

_1301424449__brigada.asm


Дата: Дек 4, 2003 21:34:16

и второй

1962950530__brigada.asm


Дата: Дек 6, 2003 14:53:02 · Поправил: bsl_zcs

Прошу прощения за задержку с ответом - уезжал по делам.

2 q_q: ;) Нет там бага. Обрати внимание, там же используется разность, чтобы исключить влияние переполнения. Финт ушами старый как мир. Не думаю, что нужно объяснять тебе про представление отрицательных чисел в дополнительном коде...

2 EvilsInterrupt: А у тебя в последнем варианте бага есть. И не одна.

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

Во-вторых, если поменять в твоём коде jne wait3 на jbe wait3, в полный рост проявится бага, о которой говорил q_q. А именно, когда значение счётчика подойдёт достаточно близко к границе переполнения, а ты добавишь к нему свою задержку, переполнение произойдёт, и результат станет маленьким числом. Твоё сравнение сразу же сработает и перейдёт к следующей ноте, с которой произойдёт то же самое, и, в конечном итоге, вся мелодия моментально кончится.

Вот то вычитание, о котором ты спрашивал, "конкретно говорит" о том, как это надо делать: сохраняется начальное значение счётчика тиков, потом в цикле берётся текущее и от него отнимается начальное. В результате, получается количество прошедших тиков вне зависимости от того, произошло за это время переполнение счётчика или нет.

Смотри, допустим счётчик равен 0FFFBh. До переполнения ему осталось пять тиков. Через эти пять тиков он станет равен нулю, ещё через пять - пяти. 5 - 0FFFBh = 10, разумеется при проведении подсчётов в 16 битах.

Надеюсь, доступно изложил. Разжевать больше я уже не в состоянии. :)

Дальше, shr bx,1 у меня поставлено, для того, чтобы подогнать скорость под мелодию, которая была в твоём исходнике. Я же писал: ...придётся поправить длительность нот. Или забить. ;) Я в нотной записи совсем не разбираюсь, но мне почему-то кажется, что не у каждого похоронного марша длительность целой ноты - 4 секунды. ;)

Насчёт достаточности или недостаточности шага в 55 мс:
кто-нибудь помнит адлибовские трекеры и их форматы? Мне их когда-то попадалось два разных: hsc-tracker и rad-tracker. Так вот, проигрыватель первого из них работал на стандартной частоте таймера, тем не менее, люди делали на нём удивительные вещи. Второй уже немного разгонял таймер - в доке было написано что-то про то, что настоящим профессионалам стандартной скорости в некоторых случаях может не хватать. ;) Так вот, я очень сомневаюсь, что кто-нибудь окажется в состоянии различить на слух это в исполнении спикера, особенно, учитывая то, как они в последнее время деградировали. ;)

Если соберёшься играть чем-нибудь кроме спикера, тем же адлибом или general midi, то воспользуйся советами q_q и Black_mirror: разгони таймер, и веди воспроизведение из обработчика таймерного прерывания. Так, в общем-то, обычно это и делалось. Только не стоит заморачиваться с прерываниями по переполнению - при разогнаном таймере всё равно нужно самому обрабатывать каждое прерывание, чтобы часы не убегали.

Говорят, винды дают досовским задачам разгонять таймер до двух килогерц. Сам я только на один килогерц гнал. Работало под всеми доступными на тот момент виндами.


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


ЗЫ. А ещё под голым досом был совершенно панковский способ делать задержки порядка десятых долей секунды. ;) Длительность задержки в тех самых тиках таймера подавалась ему в регистре CX, а сам код состоял из двух команд: один HLT и один LOOP на него. ;)


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.055