nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 13:07



Reply to topic  [ 16 posts ]  Go to page Previous  1, 2
SPMX42SE+SB 
Author Message
Banned
User avatar

Joined: 04 Jan 2013 10:09
Posts: 397
Location: 95.24.178.158
Reply with quote
Stan wrote:
Здесь мы WAV-файл, представленный отсчетами через нормальный ADC, пытаемся воспроизвести через РС-спикер, используя методы ШИМ-модуляции.
При этом отмечаем, что алгоритм:
Code:
— если разность больше нуля, подаем на встроенный динамик логическую единицу, иначе — логический нуль (если же данный байт содержит именно число 128, не изменяем логический уровень на входе динамика вовсе);
— отрабатываем цикл задержки до обработки следующего байта (длительность задержки нужно подобрать в зависимости от используемого языка программирования и тактовой частоты процессора);

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

Теперь я алгоритм ШИМ-модуляции улучшил, задействовав интервальный таймер.
Основная идея: амплитуде сэмпла из wav-файла ставим в соответствие длительность
импульса из таблицы.
Code:
'=======================================================
'  ДЕМОНСТРАЦИЯ ВОСПРОИЗВЕДЕНИЯ WAV-ФАЙЛОВ МЕТОДОМ ШИМ
'=======================================================
'
'&H61 - порт В микросхемы 8255
'&H42 - порт канала 2 таймера (звуковой сигнал)
'&H43 - порт команд установки таймера

DEFINT A-Z
  DIM Mas%(0 TO 32766) '--------- Буферный массив

'--- Таблица длительностей импульсов для канала 2 интервального таймера
  DIM SAMP(0 TO 255) AS INTEGER

'--- заполняем таблицу длительностей импульсов
    FOR i = 0 TO 255            '--- length of DATA to read
       READ R                   '--- read
       SAMP(i) = R              '--- put into array
    NEXT i                      '--- until 255

CONST Slp% = 530 '--- Задержка между отсчетами звука (подбирается)

CLS

'--- Ввод имени wav-файла (8 SYMB +"."3)
' INPUT "Введите имя wav-файла"; N$
N$ = "C:\QBASIC\HELLOW.WAV" '--- файл должен быть 8 бит 8000...11025... Гц - взять в этой ветке

'--- Открытие файла в двоичном режиме
OPEN N$ FOR BINARY AS #1  '  fl& > 32766
   fl& = LOF(1) '----- Определение длины файла
IF fl& < 2 THEN CLOSE #1: KILL N$: PRINT "File not found": END
IF fl& > 32766 THEN fl& = 32766

   FOR i& = 0 TO fl& '--- Чтение wav-файла в Mas%(i&)
       GET #1, i& + 1, Mas%(i&)'--- Buf
   NEXT i&

 PRINT
 PRINT "  Нажмите любую клавишу для воспроизведения звука  "
 PRINT
'--- Open Gate Timer_2, Speaker="0"
R = INP(&H61) AND &HFE
  OUT &H61, R
'---Ожидание нажатия клавиши
    DO: LOOP WHILE INKEY$ = ""

'---- Set up the internal speaker & Timer_2 ---
  OUT &H43, &HB0 '--- Set Timer_2 "прерыв.терм.счета, Low, High bytes"
  OUT &H42, &H01 '--- Stop
  OUT &H42, &H00 '--- Timer_2

  OUT &H43, &H90 '--- Set Timer_2 "прерыв.терм.счета, only Low byte"

  R = INP(&H61) OR 3 '--- Open Gate Timer_2, Speaker="1"
  OUT &H61, R

 FOR i& = 44 TO fl& '--- Перебор байтов (с 44-го)
    Bt% = Mas%(i&)  '--- Получить целое (2 байта)
   DEF SEG = VARSEG(Bt%)
       bLo% = PEEK(VARPTR(Bt%))     '--- Get Low  byte
       bHi% = PEEK(VARPTR(Bt%) + 1) '--- Get High byte
   DEF SEG
'----- Определение интервала для таймера -------------
       Bt% = SAMP(bLo%)
'----- Send Value to the Timer_2 Port
       OUT &H42, Bt%
 FOR j% = 0 TO Slp% '---Задержка
 NEXT j%
'----- Определение интервала для таймера -------------
       Bt% = SAMP(bHi%)
'----- Send Value to the Timer_2 Port
       OUT &H42, Bt%
 FOR j% = 0 TO Slp% '---Задержка
 NEXT j%

NEXT i&

'---- Reset the Speaker & Timer_2 ---
OUT &H43, &HB6
R = INP(&H61) AND &HFC
OUT &H61, R

END

'--- Timer Table for WAVE Samples ---------------------------------
'DATA  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2
'DATA  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4
'DATA  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5
'DATA  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6
'DATA  6,  6,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8
'DATA  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9
'DATA  9,  9, 10, 10, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 16, 17
'DATA 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 33, 34
'DATA 35, 36, 38, 39, 40, 41, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53
'DATA 54, 55, 57, 58, 58, 59, 60, 61, 62, 63, 64, 64, 65, 66, 66, 67
'DATA 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68
'DATA 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70
'DATA 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71
'DATA 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72
'DATA 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74
'DATA 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75

DATA   2,  2,  2,  2,  2,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
DATA   4,  4,  4,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  8,  8,
DATA   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, 10, 10, 10, 10, 10,
DATA  10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
DATA  12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16,
DATA  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18,
DATA  18, 18, 20, 20, 20, 20, 22, 22, 24, 24, 26, 28, 28, 30, 32, 34,
DATA  34, 36, 38, 40, 42, 44, 46, 48, 52, 54, 56, 58, 60, 62, 66, 68,
DATA  70, 72, 76, 78, 80, 82, 86, 88, 90, 92, 96, 98,100,102,104,106,
DATA 108,110,114,116,116,118,120,122,124,126,128,128,130,132,132,134,
DATA 134,134,134,134,134,136,136,136,136,136,136,136,136,136,136,136,
DATA 136,136,138,138,138,138,138,138,138,138,138,138,138,140,140,140,
DATA 140,140,140,140,140,140,140,140,140,140,142,142,142,142,142,142,
DATA 142,142,142,142,142,144,144,144,144,144,144,144,144,144,144,144,
DATA 144,144,146,146,146,146,146,146,146,146,146,146,146,148,148,148,
DATA 148,148,148,148,148,148,148,148,148,148,150,150,150,150,150,150
'------------------------------------------------------------------


Звук поприятнее, но вполне естественно появляется высокочастотный шум, характерный для метода ШИМ-модуляции.
Под Windows (ecли она допускает прямое обращение к портам) звук хуже, появляются щелчки.
Таблиц длительностей импульсов две: первая - закомментированная, во второй - удвоенные значения длительностей из первой, что делает звук громче.
Можно попробовать утроить длительности, но при этом надо помнить про ограничения, связанные с частотой дискретизации:

Частота на входе системного таймера: F=1193182 Hz; при этом период T=0,838e-6S = 0,838uS; ~ 1uS
При частоте дискретизации звука Fq = 8000 Hz; интервал между отсчетами Tq=1/Fq = 1/8000 = 0,000125S = 125uS
Аналогично:
Fq = 11025 Hz; Tq=1/Fq = 1/11025 = 0,0000907S = 90,7uS
Fq = 22050 Hz; Tq=1/Fq = 1/22050 = 0,00004535S = 45,35uS


То есть, для частоты дискретизации звука Fq = 8000 Hz максимальная длительность импульса 150 периодов таймера соответствуют ~124uS, что практически на пределе периода 125uS.
Поэтому для частоты дискретизации Fq = 11025 Hz эти длительности уже не подойдут.

Интервал между сэмплами здесь подбирается эмпирически:
CONST Slp% = 530 '--- Задержка между отсчетами звука (подбирается)
как выяснилось ранее, программный подбор этой задержки всё равно требует эмпирических коэффициентов.

Лучшего результата можно достичь, переписав прерывание INT_8 канала 0 таймера и использовав его для отсчета интервалов между семплами.
Но Windows в ряде случаев "недоволен" таким решением, поэтому задержка реализована циклом.


Lavr: Давайте "битвы оффтопов" прекратим!


28 Mar 2015 09:58
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 16 posts ]  Go to page Previous  1, 2

Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.