Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/25: Рейтинг темы: голосов - 25, средняя оценка - 4.92
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135

Открыть файл и воспроизвести через порт звуковой карты

03.11.2010, 12:55. Показов 4685. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Задача: нужно воспроизвести файл (как Я понял не обязательно звуковой). Открыть файл и послать непрерывный поток данных на порт звукой карты, чтобы та их воспроизводила как звук)). Имеется исходник, но также имеются и проблемы:
Запускаю в DOS 6.22 - ничего не происходит;
Запускаю в дос бокс - ошибка открытия файла. Наверное путь не так указал ( думаю, если ФС NTFS, то пытаться не стоит) , Закинул звуковой файл и саму прогу на дискету, и ничего... Вот исходный код, с комментариями))). Кто подскажет в чём проблема???

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
; wavdir.asm
; воспроизводит файл c:\windows\media\tada.wav, не используя DMA
; нормально работает только под DOS в реальном режиме
; (то есть не в окне DOS (Windows) и не под EMM386, QEMM или другими 
; подобными программами)
;
; Компиляция:
; TASM:
;  tasm /m wavdir.asm
;  tlink /t /x wavdir.obj
; MASM:
;  ml /c wavdir.asm
;  link wavdir.obj,,NUL,,,
;  exe2bin wavdir.exe wavdir.com
; WASM:
;  wasm wavdir.asm
;  wlink file wavdir.obj form DOS COM
;
 
FILESPEC equ 'a:\tada.wav' ; имя файла tada.wav с 
            ; полным путем (замените на c:\windows\tada.wav для 
            ; старых версий Windows)
SBPORT equ 220h ; базовый порт звуковой платы (замените, если у вас он 
        ; отличается)
 
    .model  tiny
    .code
    .186            ; для pusha/popa 
org 100h        ; COM-программа
start:
    call    dsp_reset   ; сброс и инициализация DSP
    jc  no_blaster
    mov bl,0D1h ; команда DSP D1h 
    call    dsp_write   ; включить звук
    call    open_file   ; открыть и прочитать tada.wav
    call    hook_int8   ; перехватить прерывание таймера
    mov bx,5        ; делитель таймера для частоты 22 050 Hz
                ; (на самом деле соответствует 23 867 Hz)
    call    reprogram_pit   ; перепрограммировать таймер
 
main_loop:          ; основной цикл
    cmp byte ptr finished_flag,0
    je  main_loop   ; выполняется, пока finished_flag равен нулю
 
    mov bx,0FFFFh   ; делитель таймера для частоты 18,2 Hz
    call    reprogram_pit   ; перепрограммировать таймер
    call    restore_int8    ; восстановить IRQ0
no_blaster:
    ret
 
buffer_addr dw  offset buffer   ; адрес текущего играемого байта
old_int08h  dd  ?       ; старый обработчик INT 08h (IRQ0)
finished_flag   db  0   ; флаг завершения
filename    db  FILESPEC,0  ; имя файла tada.wav с полным путем
 
; обработчик INT 08h (IRQ0)
; посылает байты из буфера в звуковую плату
int08h_handler  proc    far
    pusha           ; сохранить регистры
    cmp byte ptr cs:finished_flag,1 ; если флаг уже 1,
    je  exit_handler        ; ничего не делать,
    mov di,word ptr cs:buffer_addr ; иначе: DI = адрес текущего 
                    ; байта
    mov bl,10h      ; команда DSP 10h
    call    dsp_write       ; непосредственный 8-битный вывод
    mov bl,byte ptr cs:[di] ; BL = байт данных для вывода
    call    dsp_write
    inc di          ; DI = адрес следующего байта
    cmp di,offset buffer+27459  ; 27 459 - длина звука в tada.wav,
    jb  not_finished        ; если весь буфер пройден,
    mov byte ptr cs:finished_flag,1 ; установить флаг в 1,
not_finished:               ; иначе:
    mov word ptr cs:buffer_addr,di ; сохранить текущий адрес
exit_handler:
    mov al,20h      ; завершить обработчик аппаратного прерывания,
    out 20h,al      ; послав неспецифичный EOI (см. гл. 1.2.10)
    popa            ; восстановить регистры
    iret
int08h_handler  endp
 
; процедура dsp_reset
; сброс и инициализация DSP
dsp_reset proc near
    mov dx,SBPORT+6 ; порт 226h - регистр сброса DSP
    mov al,1    ; запись единицы в него начинает инициализацию
    out dx,al
    mov cx,40   ; небольшая пауза
dsploop:
    in  al,dx
    loop    dsploop
    mov al,0    ; запись нуля завершает инициализацию
    out dx,al   ; теперь DSP готов к работе
; проверить, есть ли DSP вообще
    add dx,8    ; порт 22Eh - состояние буфера чтения DSP
    mov cx,100
check_port:
    in  al,dx       ; прочитать состояние буфера
    and al,80h  ; проверить бит 7
    jz  port_not_ready  ; если ноль - порт еще не готов
    sub dx,4    ; иначе: порт 22Ah - чтение данных из DSP
    in  al,dx
    add dx,4    ; и снова порт 22Eh, 
    cmp al,0AAh ; если прочиталось число AAh - DSP присутствует
            ; и действительно готов к работе,
    je  good_reset
port_not_ready:
    loop    check_port ; если нет - повторить проверку 100 раз
bad_reset:
    stc     ; и сдаться
    ret     ; выход с CF = 1,
good_reset:
    clc     ; если инициализация прошла успешно
    ret     ; выход с CF = 0
dsp_reset endp
 
; процедура dsp_write
; посылает байт из BL в DSP
dsp_write proc near
    mov dx,SBPORT+0Ch ; порт 22Ch - ввод данных/команд DSP
write_loop:     ; подождать готовности буфера записи DSP
    in  al,dx       ; прочитать порт 22Ch
    and al,80h  ; и проверить бит 7,
    jnz write_loop ; если он не ноль - подождать еще,
    mov al,bl       ; иначе:
    out dx,al       ; послать данные
    ret
dsp_write endp
 
; процедура reprogram_pit
; перепрограммирует канал 0 системного таймера на новую частоту
; Ввод: BX = делитель частоты
reprogram_pit   proc    near
    cli     ; запретить прерывания
    mov al,00110110b ; канал 0, запись младшего и старшего байтов,
                ; режим работы 3, формат счетчика - двоичный
    out 43h,al  ; послать это в регистр команд первого таймера
    mov al,bl       ; младший байт делителя -
    out 40h,al  ; в регистр данных канала 0
    mov al,bh       ; и старший байт -
    out 40h,al  ; туда же
    sti     ; теперь IRQ0 вызывается с частотой 1 193 180/BX Hz
    ret
reprogram_pit   endp
 
; процедура hook_int8
; перехватывает прерывание INT 08h (IRQ0)
hook_int8 proc  near
    mov ax,3508h    ; AH = 35h, AL = номер прерывания
    int 21h     ; получить адрес старого обработчика
    mov word ptr old_int08h,bx  ; сохранить его в old_int08h
    mov word ptr old_int08h+2,es
    mov ax,2508h    ; AH = 25h, AL = номер прерывания
    mov dx,offset int08h_handler ; DS:DX - адрес обработчика
    int 21h     ; установить обработчик
    ret
hook_int8 endp
 
; процедура restore_int8
; восстанавливает прерывание INT 08h (IRQ0)
restore_int8    proc near
    mov ax,2508h    ; AH = 25h, AL = номер прерывания
    lds dx,dword ptr old_int08h ; DS:DX - адрес обработчика
    int 21h     ; установить старый обработчик
    ret
restore_int8    endp
 
; процедура open_file
; открывает файл filename и копирует звуковые данные из него, считая его файлом 
; tada.wav, в буфер buffer
open_file proc near
    mov ax,3D00h    ; AH = 3Dh, AL = 00
    mov dx,offset filename ; DS:DX - ASCIZ-имя файла с путем
    int 21h     ; открыть файл для чтения,
    jc  error_exit  ; если не удалось открыть файл - выйти
    mov bx,ax       ; идентификатор файла в BX
    mov ax,4200h    ; AH = 42h, AL = 0
    mov cx,0        ; CX:DX - новое значение указателя
    mov dx,38h ; по этому адресу начинаются данные в tada.wav
    int 21h     ; переместить файловый указатель
    mov ah,3Fh  ; AH = 3Fh
    mov cx,27459 ; это - длина звуковых данных в файле tada.wav
    mov dx,offset buffer ; DS:DX - адрес буфера
    int 21h     ; чтение файла
    ret
error_exit:         ; если не удалось открыть файл
    mov ah,9        ; AH = 09h
    mov dx,offset notopenmsg ; DS:DX = сообщение об ошибке
    int 21h     ; открыть файл для чтения
    int 20h     ; конец программы
notopenmsg  db  'Could not open file',0Dh,0Ah
        db  'Exiting',0Dh,0Ah,'$'
open_file endp
 
buffer:     ; здесь начинается буфер длиной 27 459 байтов
    end start
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.11.2010, 12:55
Ответы с готовыми решениями:

Как воспроизвести звуковой файл?
Привет всем! Подскажите, пожалуйста, модуль для воспроизведения музыки(хотя бы .mp3) И как можно реализовать воспроизведении музыки...

Воспроизвести звуковой файл (ручками)
Возможно ли это? если да, то как?

Как воспроизвести звуковой файл ресурса
Как воспроизвести в AxWindowsMediaPlayer файл из ресурса? звуковой обычный wav закинут в ресурс. как прописать его в качестве URL для...

5
2014 / 1286 / 61
Регистрация: 05.06.2010
Сообщений: 2,213
03.11.2010, 13:21
это вроде пример из Зубкова? Я помню у меня на старой звуковухе работало, потом заменил - перестало. Звуковуха должна быть совместима с sound blaster (в винде на уровне драйвера это все эмулируется). Попробуй поменять базовый порт. Не помню точно, вроде с 220h до 22fh - если не заработает, твоя звуковуха не совместима с sound blaster
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
04.11.2010, 16:38  [ТС]
Мляяя, потеря потерь, у меня звуковая внешняя, есть ещё встроенная (выключена), думаю стоит попробывать. А с какой громкостью будет проигрываться звук ???? если получится, а то у меня 5.1, не хотелось бы, чтоб на максимуме заиграло))

Пример, да, из Зубкова, там ещё есть при помощи DMA воспроизвести. Правда так же - безрезультатно.
0
4190 / 1838 / 221
Регистрация: 06.10.2010
Сообщений: 4,124
04.11.2010, 18:41
Используй DOSBox для запуска программы. Порты настраиваются в файле "dosbox.conf" в разделе "[sblaster]".
0
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.11.2010, 13:20  [ТС]
Цитата Сообщение от murderer Посмотреть сообщение
Используй DOSBox для запуска программы. Порты настраиваются в файле "dosbox.conf" в разделе "[sblaster]".
Cпасибо за ссылку, у меняесть эта прога. Запускал через неё, правда в настройках ничего не менял. Да и как то не верится, что если поменять порт в настройках бокса, то всё будет работать. Проще тогда в самой программе изменить.

Вопрос: Если у меня звуковая C-MEDIA, то у ней порты тоже свои(уникальные, как у бластера), или ОС сама назначает номера портов "по умолчанию"(стандартизированно) для разных типов устройств??
0
4190 / 1838 / 221
Регистрация: 06.10.2010
Сообщений: 4,124
05.11.2010, 19:12
DOSBox может эмулировать звуковую карту. Просто укажи ему
Code
1
2
3
4
sbtype=sb16
sbbase=220
irq=5
dma=1
И в своей проге используй те же порты и прерывания.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.11.2010, 19:12
Помогаю со студенческими работами здесь

Как воспроизвести звуковой файл в Java?
Помогите пожалуйста! Пришлите пример программы которая воспроизводит звуковой файл с расширением mp3.Если можно с подробными комментариями.

Воспроизвести звуковой файл при щелчке по кнопке
Не подскажите как можно сделать так, чтобы если нажал на кнопку button воспроизводил звуковой файл?

Как воспроизвести звуковой файл (wav или mp3)
Знаю про PLAY И SOUND,но это пищание со спикера пилит по мозгам , хотелось бы вывод собственно на колонки с файлов.

Как мне воспроизвести звуковой сигнал при получении сообщений через SignalR?
Пишу чат на .NET Core и SignalR Core. Мне нужно воспроизводить звуковые сигналы действий (отправка сообщений, получение сообщений). Как я...

Звуковой файл в COM-порт
Подскажите как произвести телефонный звонок модем (Dial-Up) на виртульном COM-порте, и воспроизвести звуковой файл.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru