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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.10.2010, 18:12   #1
my_sappho_story
Пользователь
 
Аватар для my_sappho_story
 
Регистрация: 20.10.2010
Сообщений: 29
Стрелка программная генерация звука на Ассемблире

ММмм, если есть подключенный к порту вывода динамик, то он может пищать.
Но как составить программу, которая будет формировать звуковой сигнал от динамика в компьютере, с частотой 1200 Гц и длительностью 4 секунд?
Нужно программно выводить на линию выходного порта последовательность нулей и единиц, чередующихся с периодом.
Есть какие-то идеи и способы как точнее составить код?
my_sappho_story вне форума Ответить с цитированием
Старый 22.10.2010, 18:24   #2
bondik
Форумчанин
 
Регистрация: 24.04.2008
Сообщений: 300
По умолчанию

и чего сложного?
bondik вне форума Ответить с цитированием
Старый 22.10.2010, 18:26   #3
bondik
Форумчанин
 
Регистрация: 24.04.2008
Сообщений: 300
По умолчанию

Лабу как то сдавал,мелодию из бумера воспроизводит.Только не забывай что XP не даст прерывание юзать

Код:
#include <conio.h>
#include <dos.h>
#include <stdio.h>

#define do 261
#define re 293
#define mi 329
#define fa 349
#define sol 392
#define lya 440
#define si 493

void main()
{
clrscr();





int song[100] = {mi,sol,sol,mi,lya,sol,lya,sol,lya,sol,lya,sol,lya,si};
int dlit[100]=   {3, 4,   3, 4,  2, 2,  2 , 2  ,2   ,2 , 2 ,2,  2,  4};

for (int i=0;i<14;i++)
{
outp(0x43,0xb6); //101 101 10

unsigned int del=1193180/song[i];

outp(0x42,(del & 0x00FF)); //low

outp(0x42,(del >> 8)); //hi

unsigned int read=inp(0x61);
outp(0x61,(read | 3));

																for(int a=1;a<dlit[i];a++){
							 _asm {

				 MOV CX, 0002h
				 MOV DX, 80DEh
				 MOV AH, 86h
				 INT 15h
								 };

}

outp(0x61,(read & 252));
															 for(a=1;a<dlit[i];a++){
								 _asm {

				 MOV CX,0000h
				 MOV DX,5B8Dh
				 MOV AH, 86h
			   INT 15h
                          };

}

}


	
getch();
}
bondik вне форума Ответить с цитированием
Старый 22.10.2010, 18:27   #4
bondik
Форумчанин
 
Регистрация: 24.04.2008
Сообщений: 300
По умолчанию

И про весы не забывай
bondik вне форума Ответить с цитированием
Старый 22.10.2010, 21:42   #5
alexcoder
Форумчанин
 
Регистрация: 31.05.2009
Сообщений: 786
По умолчанию

Код:
            ;
            ; подпрограмма генерации звука
            ; Вход: АX= частота звука в Гц
            ;
 Sound      proc     near
            push     ax        ;сохранить регистры
            push     bx
            push     dx
            mov      bx,ax     ;частота
            mov      ax,34DDh
            mov      dx,12h    ;(dx,ax)=1193181
            cmp      dx,bx     ;если bx < 18Гц, то выход
            jnb      Done      ;чтобы избежать переполнения
            div      bx        ;ax=(dx,ax)/bx
            mov      bx,ax     ;счетчик таймера
            in       al,61h    ;порт РВ
            or       al,3      ;установить биты 0-1
            out      61h,al
            mov      al,00001011b   ;управляющее слово таймера:
                               ;канал 2, режим 3, двоичное слово
            mov      dx,43h
            out      dx,al     ;вывод в регистр режима
            dec      dx
            mov      al,bl
            out      dx,al     ;младший байт счетчика
            mov      al,bh
            out      dx,al     ;старший байт счетчика
 Done:
            pop      dx        ;восстановить регистры
            pop      bx
            pop      ax
            ret
 Sound      endp
            ;
Для прекращения:
Код:
            ;подпрограмма выключения звука
            ;
 No_Sound   proc     near
            push     ax
            in       al,61h    ;порт РВ
            and      al,not 3  ;сброс битов 0-1
            out      61h,al
            pop      ax
            ret
 No_Sound   endp
Код:
      Второй  способ   генерации  звука  состоит   в  том,  чтобы
 генерировать звуковые импульсы не  выходом таймера, а установкой
 и сбросом бита 1 в регистре  РВ. Для управления задержками можно
 использовать программный цикл, например:

           ;
           ; Программа генерации звука
           ; Вход: N=количество импульсов
           ;       FREQ=длительность импульса
           ;
           in        al,61h         ;порт РВ
           and       al,not         ;сброс бита 0
           mov       dx,N
 Repeat:
           or        al,2
           out       61h,al         ;установить бит 1
           mov       cx,FREQ
 Wait_On:
           loop      Wait_On
           and       al,not 2       ;сбросить бит 1
           out       61h,al
           mov       cx,FREQ
 Wait_Off:
           loop      Wait_Off
           dec       dx
           jnz       Repeat

      Программирование   этого  способа   основано  на  следующих
 формулах.  Если Т  - длительность  звучания в  сек, f  - частота
 звука в Гц, а t - тактовая частота процессора ПЭВМ, то

      N=T*f; FREQ=t/(34*f).

      Константа 34  объясняется тем, что  длительность каждого из
 циклов Wait_on и Wait_off  приблизительно равна (17*cx) машинных
Со вторым способом скорей всего возникнет проблема из-за большой частоты процессора и многозадачности.
Помощь с программами:
vk.com/alexcoder1
e-mail: informatik101@mail.ru
alexcoder вне форума Ответить с цитированием
Старый 24.10.2010, 21:21   #6
my_sappho_story
Пользователь
 
Аватар для my_sappho_story
 
Регистрация: 20.10.2010
Сообщений: 29
По умолчанию

А почему не пищит? Ни одних из вариантов программ не вынуждает издавать звуки из динамика. Почему?
my_sappho_story вне форума Ответить с цитированием
Старый 25.10.2010, 00:32   #7
Gambler
Игрок
Форумчанин
 
Аватар для Gambler
 
Регистрация: 29.10.2006
Сообщений: 367
По умолчанию

Код:
stseg   segment para    stack
        dw      16      dup(?)
stseg   ends
dseg    segment para
	Notes	dw	392,586,520,619,586,454,520,586,619,586,392,392,586,520,619,586,586,520,454,431,454,336,392,586,520,619,586,586,520,586,619,586,392,586,520,454,431,454,303,392,454,431,392,346,392;массив нот
	Time	dw	3,3,3,3,12,3,3,3,6,6,24,3,3,3,3,12,3,3,3,6,6,24,3,3,3,3,12,3,3,3,6,6,24,3,3,3,6,6,24,3,3,3,3,6,24;массив длительностей
	Count	dw	45							;кол-во элементов в массиве
dseg    ends
cseg    segment para
lab2    proc    far
        assume  cs:cseg,ds:dseg,ss:stseg
        push    ds						
        mov     ax,0
        push    ax
        mov     ax,dseg
        mov     ds,ax
;********НАЧАЛО ПРОГРАММЫ************
		mov		cx,Count			;кол-во элементов в массиве
CYCLE:
		mov		si, OFFSET Notes	;указатель на начало массива нот
		mov		dx,Count			;записываем кол-во элем. во врем. перем-ю
		sub		dx,cx				;вычитаем из него кол-во повторений
		add		dx,dx				;умножаем на два
		add		si,dx				;указатель на текущую ноту
		mov     bx,[si]				;загружаем ноту в регистр
		mov		dx,12h				;готовим ст. биты делимого 
		mov		ax,34DCh			;готовим мл. биты делимого
        div     bx					;ax='dx'+'ax'/bx
        mov     bx,ax				;то же самое - в bx
        in      al,61h				;читаем данные с порта 61
        or      al,3				;устанавливаем биты 0-1 в "1"
        out     61h,al				;изм-ное число записываем в порт
        mov     al,00001011b		;управляющее слово таймера:
									;канал 2, режим 3, двоичное слово
        out     43h,al				;вывод в регистр режима
        mov     al,bl
        out     42h,al				;младший байт счетчика
        mov     al,bh
        out     42h,al				;старший байт счетчика
		mov		si, OFFSET Time		;указатель на начало массива длительностей		
		mov		dx,Count			;кол-во элементов
		sub		dx,cx				;вычитаем кол-во совершенных повторений
		add		dx,dx				;умножаем н два
		add		si,dx				;указатель на длительность текущей ноты
        push    [si]				;длительность ноты в регистр
		call	delay				;процедура задержки
		pop		si					чистим стек
		in		al,61h				;читаем данные из порта 61
        and		al,0FCh				;сбрасываем биты 0-1 на "0"
        out		61h,al				;записываем в порт
		push	2					;в стек - длительность паузы
		;call	delay				;процедура задержки
		pop		si					;чистим стек
		loop CYCLE					;цикл по всем элементам массива
		ret
lab2    endp

;процедура задержки (параметр - длительность задержки - в стеке)
delay	proc
	push	ax		;сохраняем регистры
	push	si
	push	bx
	push	cx
	mov		bp,sp			;указатель на начало стека
	mov		si,[bp+0Ah]		;выбираем переданный параметр
	mov		ah,0			;выбираем функцию
	int		1Ah				;кол-во тиков
	mov		bx,dx			;сохраняем считанное число
	add		bx,si			;и прибавляем к нему время задержки
DELAY_CYCLE:
	int		1Ah				;снова проверяем время
	cmp		dx,bx			;сравниваем со временем конца задержки
	jna		DELAY_CYCLE		;если полученное время меньше нужного - на след.повтор
	pop		cx				;восстанавливаем регистры из стека
	pop		bx
	pop		si
	pop		ax
	ret		
delay	endp
cseg    ends
        end     lab2
Вот пример. У меня в XP работал (хотя я тоже слышал что система не дает работать с прерываниями). Код может быть корявый. Когда писал - не сильно разбирался. Сейчас лень вникать. Компилить в TASM.
Жизнь всегда игра. Но смерть - не всегда поражение.

#define true (Math.random()>0.5) //Удачной отладки
Gambler вне форума Ответить с цитированием
Старый 25.10.2010, 00:38   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в режиме виртуального 8086 дает все юзать.(по умолчанию COM так и грузятся)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 25.10.2010, 01:42   #9
my_sappho_story
Пользователь
 
Аватар для my_sappho_story
 
Регистрация: 20.10.2010
Сообщений: 29
По умолчанию

не издает никак звуков '(
my_sappho_story вне форума Ответить с цитированием
Старый 25.10.2010, 10:50   #10
Gambler
Игрок
Форумчанин
 
Аватар для Gambler
 
Регистрация: 29.10.2006
Сообщений: 367
По умолчанию

у тебя динамик то есть?
Жизнь всегда игра. Но смерть - не всегда поражение.

#define true (Math.random()>0.5) //Удачной отладки
Gambler вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программная работа со звуком _-Re@l-_ Общие вопросы Delphi 7 28.01.2011 11:49
Программная эмуляция джойстика overloaded0 Win Api 0 25.10.2008 00:02
программная работа с параметром Sack Microsoft Office Access 4 29.09.2008 11:22
Генерация звука N!ckeL Общие вопросы Delphi 1 19.06.2008 09:19
Генерация звука (assembler) SerGeO3x Помощь студентам 1 17.06.2008 19:01