Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.11.2011, 20:02   #1
-=Andriushka=-
Пользователь
 
Регистрация: 17.02.2011
Сообщений: 91
По умолчанию проиграть на ассемблере какую-нибудь мелодию из классики

добрый вечер!есть такая программа:
Код:
DSEG SEGMENT 
BEAT DB 10,9,8,7,6,5,4,3,2  ;длительность нот 
FREQUENCY DW 2280,2031,1809,1709 
                     DW 1521,1353,1207,1139;длительность частот 
MELODY DB 1,2,3,4,5,6,7,8,0FFH; номер частоты нот
DSEG ENDS 
 
SSEG SEGMENT STACK 
db 256 dup(0) 
SSEG ENDS 
 
CSEG SEGMENT 
assume cs:CSEG,ds:DSEG 
start:  mov ax,DSEG 
         mov ds,ax 

;---инициализация 
PORT_B EQU 61H 
COMMAND_REG EQU 43H 
LATCH2 EQU 42H 
	IN AL,PORT_B                   ;получаем текущий статус
	OR AL,00000011B              ;разрешаем динамик и таймер 
	OUT PORT_B,AL               ;заменяем байт  
	MOV SI,0                          ;инициализируем указатель 
	MOV AL,0B6H                   ;установка для канала 2 
	OUT COMMAND_REG,AL ;посылаем в командный регистр 
;---смотрим ноту, получаем ее частоту и помещаем в канал 2 
NEXT_NOTE: 
	LEA BX,MELODY  ;берем смещение для мелодии 
	MOV AL,[BX][SI]   ;берем код n-ой ноты строки 
	CMP AL,0FFH       ;проверка на конец строки 
	JE NO_MORE       ;если конец то на выход 
	CBW                    ;переводим в слово 
;---получение частоты 
	MOV BX,OFFSET FREQUENCY  ;смещение таблицы частот 
	DEC AX                                      ;начинаем отсчет с 0 
	SHL AX,1                                   ;умножаем на 2, т.к. слова 
	MOV DI,AX                                ;адресуем через DI 
	MOV DX,[BX][DI]                       ;получаем частоту из таблицы 
;начинаем исполнение ноты    
	MOV AL,DL                 ;готовим младший байт частоты 
	OUT LATCH2,AL          ;посылаем его 
	MOV AL,DH                 ;готовим старший байт частоты 
	OUT LATCH2,AL          ;посылаем его  
;---создание цикла задержки   
	MOV AH,0                          ;номер функции чтения счетчика 
	INT 1AH                             ;получаем значение счетчика 
	MOV BX,OFFSET BEAT     ;смещение таблицы длин 
	MOV CL,[BX][SI]               ;берем длину очередной ноты 
	MOV CH,0 
	MOV BX,DX                      ;берем младшее слово счетчика 
	ADD BX,CX                       ;определяем момент окончания 
STILL_SOUND: 
	INT 1AH                          ;берем значение счетчика
	CMP DX,BX                    ;сравниваем с окончанием 
	JNE STILL_SOUND          ;неравны-продолжаем звук
	INC SI                             ;переходим к следующей ноте
	JMP NEXT_NOTE            ;
;---завершение 
NO_MORE: 
	IN AL,PORT_B   ;полчаем статус порта В
	AND AL,0FCH    ;выключаем динамик
	OUT 61H,AL       ;заменяем байт
	
MOV AX,4C00H 
INT 21H 
CSEG ENDS 
END START
задание преподователя чтобы проигралась какая нибудь мелодия из классики...но у меня не очень хорошо с классической музыкой,да и вообще с музыкой...помогите пожалуйста подправить чтобы игралась классическая мелодия!!
-=Andriushka=- вне форума Ответить с цитированием
Старый 01.12.2011, 04:38   #2
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

-=Andriushka=-
Ты какую из симфоний Бетховена предпочитаешь? 3-ью «Героическую» или 6-ую «Пасторальную». И как себе это твой преподаватель представляет?
Нотам 4 октавы соответствует
нота |частота(Гц)|делитель =1193180/частота
до диез | 277,23 |10CFh
ре 293,66 |0FDFh
ре диез |311,13| 0EFAh
ми |329,63| 0E23h
фа |349,23| 0D58h
фа диез |370| 0C98h
соль |392 |0BE3h
соль диез |415,3| 0B39h
ля |440 |0A97h
ля диез |466,16| 9FFh
си |493,88 |96Fh
до |523,25| 8E8h
для третьей октавы значение частоты из таблицы делят на 2, а для пятой октавы - умножают на 2
Берешь ноты любого произведения и в соответствии с моей таблицей вписываешь их в BEAT DB ... ;длительность нот и FREQUENCY DW ...
Для начала советую подобрать "Чижик-пыжик" и "Собачий вальс", а потом уже переходить к Бетховену
Mikl___ вне форума Ответить с цитированием
Старый 02.12.2011, 06:17   #3
KeLuut
 
Регистрация: 30.11.2011
Сообщений: 3
Сообщение

-=Andriushka=-:
Странное отношение у преподавателя к классической музыке. Классику приятнее и интереснее слушать вживую, в исполнении умелого музыканта на настоящем инструменте :) И к ассемблеру данная тема не имеет прямого отношения.

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

«Сурок» Бетховена:
Код:
10:8/7:4/7:8/7:4/7:8/6:8/5:8/6:8/7:4.4444444/@:40/7:8/6:4/6:8/5:8/6:8/7:8/6:2.66667/10:4/
10:8/7:4/7:8/7:4/7:8/6:8/5:8/6:8/7:4.4444444/@:40/7:8/6:4/6:8/10:4/10:8/7:2.66667/7:5/@:20/
7:16/6:16/5:4/5:8/4:4/4:8/3:4/3:8/4:4/4:8/5:8/6:8/7:8/5:8/6:8/7:8/6:2.66667/6:4/
7:16/6:16/5:4/5:8/4:4/4:8/3:4/3:8/4:4/4:8/5:8/6:8/7:8/6:8/5:8/6:8/7:2.66667/7:4/
Концерт соль-мажор Вивальди, отрывок из первой части:
Код:
1:8/#2:16/3:16/4:8/5:8/6:8/8:8/6:8/4:8/1:4/0:4/-1:8/0:16/-1:16/1:8/
-1:8/0:16/-3:16/0:16/-3:16/0:16/-3:16/0:16/-3:16/-1:8/-3:8/@:8/
-1:8/0:16/-3:16/0:16/-3:16/0:16/-3:16/0:16/-3:16/-1:8/-3:8/@:8/
1:8/#2:16/3:16/4:16/#2:16/1:16/#2:16/3:16/1:16/0:16/1:16/#2:16/0:16/-1:16/0:16/1:16/-1:16/
#-2:16/-1:16/0:16/#-2:16/-3:8/1:8/#2:4/3:4/4:8/@:16/
11:16/10:16/#9:16/8:16/7:16/6:16/5:16/4:8/9:8/9:32/8:32/9:32/8:32/10:8/@:16/
10:16/#9:16/8:16/7:16/6:16/#5:16/4:16/3:8/8:8/8:32/7:32/8:32/7:32/9:8/@:16/
#9:16/8:16/7:16/6:16/5:16/4:16/3:16/#2:8/7:8/7:32/6:32/7:32/6:32/8:8/@:16/
8:16/7:16/6:16/5:16/4:16/3:16/#2:16/1:8/6:8/6:32/5:32/6:32/5:32/7:8/@:16/
7:16/6:16/5:16/4:16/3:16/#2:16/1:16/0:8/5:8/
6:16/1:16/#2:16/1:16/4:16/1:16/#2:16/1:16/3:16/1:16/#2:16/1:16/3:16/1:16/#2:16/1:16/
4:16/1:16/#2:16/1:16/4:16/1:16/#2:16/1:16/3:16/1:16/#2:16/1:16/3:16/1:16/#2:16/1:16/
4:16/1:16/#2:16/1:16/4:16/1:16/#2:16/1:16/5:16/1:16/#2:16/1:16/5:16/1:16/#2:16/1:16/
6:16/1:16/#2:16/1:16/6:16/1:16/#2:16/1:16/7:16/1:16/#2:16/1:16/7:16/#2:16/3:16/#2:16/
1:8/#2:16/3:16/4:8/5:8/6:8/8:8/6:8/4:8/1:4/0:4/-1:8/0:16/-1:16/1:4/
И комментарий по формату. Числа между слешами обозначают ноту и её длительность следующим образом:
Код:
номер_ноты:делитель/
«Делитель» определяет длительность ноты по отношению к целой:
Код:
(длительность)=(длительность_целой_ноты)/(делитель)
То есть, нужно подобрать длительность целой ноты d, и рассчитывать остальные длительности относительно неё (чем короче длительность ноты, тем быстрее темп, и наоборот). Дробные значения делителя соответствуют т. н. «нецелым» нотам (например, с длительностями 1/4 + 1/8 = 4/3 ≈ 1/2.66666667).

Теперь о том, как определить нужную частоту ноты. Поскольку программа, в которой проверял правильность звучания мелодии, писалась давно и для себя, в ней не очень осмысленные обозначения (неудобные для вычислений). Что нужно сделать, чтобы получить правильную частоту звука:
  • взять число i (без «решётки») перед двоеточием в каждом случае;
  • найти ему соответствующее k:
    Код:
    k = (7 - i);
  • учитывая диезы («решётки»), по номеру k найти номера частот n (приведены значения для трёх октав):
    Код:
               n         ⇐         k
    
    ..., -12, 0,  12...  ⇐  ...,  -7,  0,  7...  (ля)
    ..., -11, 1,  13...  ⇐  ..., #-7, #0, #7...
    ..., -10, 2,  14...  ⇐  ...,  -6,  1,  8...  (си)
    ..., -9,  3,  15...  ⇐  ...,  -5,  2,  9...  (до)
    ..., -8,  4,  15...  ⇐  ..., #-5, #2, #9...
    ..., -7,  5,  17...  ⇐  ...,  -4,  3,  10... (ре)
    ..., -6,  6,  18...  ⇐  ..., #-4, #3, #10...
    ..., -5,  7,  19...  ⇐  ...,  -3,  4,  11... (ми)
    ..., -4,  8,  20...  ⇐  ...,  -2,  5,  12... (фа)
    ..., -3,  9,  21...  ⇐  ..., #-2, #5, #12...
    ..., -2,  10, 22...  ⇐  ...,  -1,  6,  13... (соль)
    ..., -1,  11, 23...  ⇐  ..., #-1, #6, #13...
    (столбцы слева соответствуют столбцам справа).
  • Определить частоту ноты по формуле:
    Код:
    freq ≈ 440.0 * 2^{n/12}
Значок «@» вместо ноты обозначает паузу соответствующей длительности.

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

Последний раз редактировалось KeLuut; 02.12.2011 в 18:10.
KeLuut вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Можно ли использовать какую нибудь другую память, например динамическую? Scan Общие вопросы .NET 3 10.11.2010 16:35
Подскажите кто-нибудь в чем отличие между system("pause"); и getch(); какую лучше использовать? Paul_AG Общие вопросы C/C++ 7 24.03.2009 19:32
через какую сетевую карту входить в инет, а через какую в лан шКОЛЯР Свободное общение 2 27.06.2008 17:55