Эта программа увеличивает громкость выбранного канала на 1000.

Code:

uses MMSystem;

 

procedure TForm1.Button1Click(Sender: TObject);

var

vol: longint;

LVol, RVol: integer;

begin

AuxGetVolume(ListBox1.ItemIndex, @Vol);

LVol := Vol shr 16;

if LVol < MaxWord - 1000

   then LVol := LVol + 1000

   else LVol := MaxWord;

RVol := (Vol shl 16) shr 16;

if RVol < MaxWord - 1000

   then RVol := RVol + 1000

   else RVol := MaxWord;

AuxSetVolume(ListBox1.ItemIndex, LVol shl 16 + RVol);

end;

 

procedure TForm1.FormCreate(Sender: TObject);

var

i: integer;

cap: TAuxCaps;

begin

for i := 0 to auxGetNumDevs - 1 do begin

   auxGetDevCaps(i, Addr(cap), SizeOf(cap));

   ListBox1.Items.Add(cap.szPname)

end;

end;

 

 

Второй вариант:

Code:

uses mmsystem;

 

function GetWaveVolume: DWord;

var

Woc : TWAVEOUTCAPS;

Volume : DWord;

begin

result:=0;

if WaveOutGetDevCaps(WAVE_MAPPER, @Woc, sizeof(Woc)) = MMSYSERR_NOERROR then

if Woc.dwSupport and WAVECAPS_VOLUME = WAVECAPS_VOLUME then

begin

WaveOutGetVolume(WAVE_MAPPER, @Volume);

Result := Volume;

end;

end;

 

procedure SetWaveVolume(const AVolume: DWord);

var Woc : TWAVEOUTCAPS;

begin

if WaveOutGetDevCaps(WAVE_MAPPER, @Woc, sizeof(Woc)) = MMSYSERR_NOERROR then

if Woc.dwSupport and WAVECAPS_VOLUME = WAVECAPS_VOLUME then WaveOutSetVolume(WAVE_MAPPER, AVolume);

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

Beep;

end;

 

procedure TForm1.Button2Click(Sender: TObject);

var

LeftVolume: Word;

RightVolume: Word;

begin

LeftVolume := StrToInt(Edit1.Text);

RightVolume := StrToInt(Edit2.Text);

SetWaveVolume(MakeLong(LeftVolume, RightVolume));

end;

 

procedure TForm1.Button3Click(Sender: TObject);

begin

Caption := IntToStr(GetWaveVolume);

end;

 

Автор MMM

 Прислал: Ненашев Илья Николаевич

 

Под WinNT/2000/XP вы можете использовать Beep(Tone, Duration) (задавать тон и продолжительность звучания). А под 9.x/Me эта функция не реализована, но можно командовать железом через порты, и сделать универсальную:

  

Code:

unit BeepUnit;

 

procedure Beep(Tone, Duration: Word); // универсальная - версию виндовса проверяет

 

procedure Sound(Freq : Word);

procedure NoSound;

 

procedure SetPort(address, Value:Word);

function GetPort(address:word):word;

 

implementation

 

procedure SetPort(address, Value:Word);

var

bValue: byte;

begin

bValue := trunc(Value and 255);

asm

   mov dx, address

   mov al, bValue

   out dx, al

end;

end;

 

function GetPort(address:word):word;

var

bValue: byte;

begin

asm

   mov dx, address

   in al, dx

   mov bValue, al

end;

GetPort := bValue;

end;

 

procedure Sound(Freq : Word);

var

B : Byte;

begin

if Freq > 18 then begin

   Freq := Word(1193181 div LongInt(Freq));

   B := Byte(GetPort($61));

   if (B and 3) = 0 then begin

     SetPort($61, Word(B or 3));

     SetPort($43, $B6);

   end;

   SetPort($42, Freq);

   SetPort($42, Freq shr 8);

end;

end;

 

procedure NoSound;

var

Value: Word;

begin

Value := GetPort($61) and $FC;

SetPort($61, Value);

end;

 

procedure Beep(Tone, Duration: Word);

begin

if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT

   then Windows.Beep(Tone, Duration)

   else begin

     Sound(Tone);

     Windows.Sleep(Duration);

     NoSound;

   end;

end;

 

end.

 Взято из forum.sources.ru

  


Вот мой старый способ, которым я извлекал звуки в Visual Basic (это было много времени назад) с помощью функций API. Ниже приведена функция, требующая на входе два параметра: тон и длительность воспроизведения. (Примечание: функции Windows API требуют гораздо большее количество параметров, но вам нужно беспокоиться только о тех, которые изменяются от вызова до вызова... т.е. только о тоне и длительности.)

 

Code:

procedure MakeSound(note, duration: integer);

{

Цель:      Проигрывание звуков на динамике PC.

Параметры: note = шаг тона (правильный диапазон с 1 по 84 (1

 

самый низкий тон и 84 самый высокий)

duration = продолжительность звучания (допустимый диапазон

с 1 по 128... но это мои догадки... чем меньше значение

тем короче продолжительность)

}

var

result: integer;

begin

{проверка на правильность величины... должно быть 1-84}

if (note < 1) or (note > 84) then

   exit;

{проверка на правильность величины... по моим догадкам, должно быть

в диапазоне от 1 до 128}

if (duration < 1) or (duration > 128) then

   exit;

{открываем звуковой канал}

result := OpenSound;

{устанавливаем размер звуковой очереди (не очищайте это! Я думаю что

каждая нота требует 6 байт.)}

result := SetVoiceQueueSize(1, 6);

{устанавливаем звуковую ноту (и ее длительность)}

result := SetVoiceNote(1, note, duration, 1);

{проигрываем ноту}

result := StartSound;

{ожидаем окончания звучания}

result := WaitSoundState(S_QUEUEEMPTY);

{закрываем звуковой канал}

CloseSound;

end;

 

Затем можно вызвать эту функцию следующим образом...

 

MakeSound(1,1);

MakeSound(32,10);

 

Эти две строчки заставят динамик вашего PC зазвучать сначала в низком диапазоне (продолжительностью в секунду или две), и затем немного дольше в более высоком диапазоне.

 Автор: Steve Keyser       

Взято с delphiworld.narod.ru

 

Если Вам не нужен компонент MediaPlayer, а сыграть звук, например, при нажатии на кнопку, нужно, воспользуйтесь функцией PlaySound. Одна из ее возможностей сыграть wav-файл.

 

Code:

uses MMsystem;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

if OpenDialog1.Execute then

   PlaySound(PChar(OpenDialog1.FileName), 0, SND_FILENAME);

end;

 

 

Автор советов: Даниил Карапетян

 

e-mail: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.

 

Автор справки: Алексей Денисов

e-mail: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.

Sound Blaster воспроизводит как синтезированный звук так и оцифровые звуки.

В этом файле будет расмотрено программирование воспроизведения цифровых

выборок через Sound Blaster DSP.

 

+-------------------------------------+-------------------------------------

| Порты ввода/вывода SoundBlaster DSP |

+=====================================+

 

Чип DSP ( Цифровой Звуковой Процессор ) программируется через пять портов,

которые определяются через базовый адрес Sound Blaster:

 

2x6h - DSP Сброс

2xAh - DSP Чтение

2xCh - DSP Запись (команды/данные) ,

состояние буфера записи DSP( Бит 7 )

2xEh - Состояние буфер чтения DSP ( Бит 7 ),

подтверждение прерывания DSP

Пятый порт только для Sound Blaster 16

2xFh - подтверждение прерывания DSP с 16 битами

 

Где x = 1 для базового адреса 210h.

x = 2 для базового адреса 220h.

.

.

x = 6 для базового адреса 260h.

 

 


+-----------+----------------------------------------------------------------

| Сброс DSP |

+===========+

 

Необходимо сбросить DSP прежде, чем начать работу с ним. Сброс осуществляется

по следующему алгоритму:

 

1) Запишите 1 в порт сброса (2x6)

2) Ждите 3 микросекунды

3) Запишите 0 в порт сброса (2x6)

4) Читайте порт состояния буфера чтения (2xE) пока бит 7 = 1

5) Опрашивайте порт данных чтения (2xA) пока вы не получите AAh.

 

Для сброса DSP требуется около 100 мкс. Если после этого вы не получили

AAh. Значит, либо нет звуковой платы, или задан был неверный базовый

адрес.

 

Пример:

 

#define MAX_BASE_SB 5

 

int bases[MAX_BASE_SB]={ 0x220, 0x230, 0x240, 0x250, 0x260 };

int baseAddrSB=0x220;

 

 

// Прочитать

 

unsigned char pascal ReadSB

(void)

{

unsigned int value;

 

while (!(inp((baseAddrSB+0xE)) & 0x80));

value = inp((baseAddrSB+0xA));

return value;

}

 

// Проверить наличие

 

char pascal CheckSB

( void )

{

int i, j;

for ( j=0; j 23 KHz. Затем младший

байт длины, потом старший.

 

WriteSB(DMA_8_BIT_DAC);

WriteSB(lo(len));

WriteSB(hi(len));

 

24h - Включение записи с ADC 8 Бит 4KHz - > 23 KHz

74h - Включение вывода на DAC 4 Бит ADPCM 4KHz - > 12 KHz

75h - Включение вывода на DAC 4 Бит ADPCM с 4KHz - > 12 KHz с байтом ссылки

76h - Включение вывода на DAC 2.6 Бит ADPCM 4KHz - > 13 KHz

77h - Включение вывода на DAC 2.6 Бит ADPCM с 4KHz - > 13 KHz с байтом ссылки

16h - Включение вывода на DAC 2 Бит ADPCM 4KHz - > 11 KHz

17h - Включение вывода на DAC 2 Бит ADPCM с 4KHz - > 11 KHz с байтом ссылки

 

ADPCM ( Адаптивная Импульсно-кодовая Модуляция) - это звуковая методика

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

чем их фактические значения. В режимах с байтами ссылки, первый байт -

фактическое начальное значение. Наличие режимов с и без байтов ссылки значит

что вы можете выводить последовательные блоки без наличия байта ссылки.

 

Bxh - программмирование режима DMA с 16 битным цифровым звуком.

( Только для SB16 )

Командная последовательность:

Команда, Режим, Lo(Length-1), Hi(Length-1):

 

Первый байт команды состоит:

 

D7 D6 D5 D4 D3 D2 D1 D0

--+--+--+--+---+----+-----+--

1 0 1 1 A/D A/I FIFO 0

---------------+----+-----+--

0=D/A 0=SC 0=off

1=A/D 1=AI 1=on

 

Общие команды:

B8 - одиночный цикл с 16-битной записи звука

B0 - одиночного цикла с 16-битным воспроизведением

BE - автоинициализируемая 16-битная запись

B6 - автоинициализируемое 16-битной воспроизведение

 

Режим:

 

D7 D6 D5 D4 D3 D2 D1 D0

---+--+-------+-----+--+--+--+--

0 0 Стерео Знак 0 0 0 0

0-Моно 0-без

1-Стерео 1-со знаком

 

Cxh - программирование режим DMA с 8-битным цифровым звуком.

( Только для SB16 )

Те же самые команды, что для 16-бит.

C8 - одиночный цикл с 8-битной записи звука

C0 - одиночного цикла с 8-битным воспроизведением

CE - автоинициализируемая 8-битная запись

C6 - автоинициализируемое 8-битной воспроизведение

 

FIFO используется чтобы удалять несогласованности в тот период выборки,

когда звуковая плата не способна получить DMA, когда это требуется.

Без FIFO плата делает попытку захвата DMA в точно тот момент, когда

требуется выборка. Если другое устройство с более высоким приоритетом

обращается к DMA, звуковая плата ожидает и скорость выборки может

уменьшаться. FIFO позволяет во время выборки с DMA быть более гибким DSP

без потери звукового качества. FIFO очищается всякий раз, когда команда

посылается DSP. В режиме одиночного цикла, DSP постоянно перепрограммируется.

С FIFO DSP может еще содержать данные, который не были выданы, когда

команда очистила DAC. Чтобы избежать этого, FIFO должен быть переключен

в режим с одиночным циклом. Затем, снова переведен в автоинициализируемый

режим, когда DSP не перепрограммируется.

 

1Ch - Включение вывода на DAC 8 Бит 4KHz - > 23 KHz с автоинциализацией

90h - Включение вывода на DAC 8 бит 4kHz - > 44 KHz с автоинициализацией

48h - Установить длину блока на пересылку перед посылкой 91h, 99h

сначала младший байт затем старший длину.

91h - Включение вывода на DAC 8 бит 4kHz - > 44 KHz стерео

99h - Включение записи с ADC 8 бит 4kHz - > 44 KHz стерео

 

WriteSB(SET_LEN_DMA_8_BIT);

WriteSB(lo(len));

WriteSB(hi(len));

WriteSB(DMA_8_BIT_DAC_HI);

 

D0h - остановить 8-битный DMA

D4h - возобновить 8-битный DMA

D5h - остановить 16-битный DMA

D6h - возобновить 16-битный DMA

Эти команды пригодны как и для автоинциализированного режима,

так и для одиночных циклов.

 

D9h - Выход из авто инициализируемого режима DMA с 16 битами

после окончания текущего блока.

DAh - Выход из авто инициализируемого режима DMA с 8 битами

после окончания текущего блока.

 

E1h - Получить номер версии DSP. После посылки этой команды, прочитайте

из DSP два байта. Первый байт - главный номер версии и второй

байт - малый номер версии. Версия 4.00 - это SB16.

 

Версия | Стерео | Частота | FIFO | 16 бит

--------+--------+----------+------+--------

< 2.00 | - | до 21379 | - | -

>= 2.00 | - | до 21379 | + | -

>= 2.01 | - | до 43478 | + | -

>= 3.00 | + | до 43478 | + | -

>= 3.01 | + | до 43478 | + | +

 


Пример определения версии:

 

int pascal VersionSB

( void )

{

char ch, ch1;

WriteSB(0xE1);

ch=ReadSB();

ch1=ReadSB();

verSB=ch<<8 | ch1;

if ( verSB>=0x200 )

Fifo=1;

if ( verSB>=0x201 )

MaxFrequency=1;

if ( verSB>=0x300 )

Stereo=1;

if ( verSB>=0x301 )

SixteenBit=1;

return verSB;

}

 

 


+----------------------+----------------------------------------------------

| Программирование DMA |

+======================+

 

 

Контроллер DMA (Прямого Доступа В память) управляет пересылками данных

между устройствами ввода/вывода и памятью без использования центрального

процессора. IBM совместимая ЭВМ имеет два контроллера DMA один для

пересылок с 8 битами и другой для пересылок с 16 битами. Контроллер DMA,

вместе с внешним регистром страницы, способен на перемещение блоков по 64 КБ.

Ниже приведена информация по программированию DMA.

 

Адреса портов для адреса DMA и регистров счета.

 

Контроллер | Адрес | Функция

---------------+---------+-----------------

DMA 1 | 00 | Канал 0 адреса

c 8 битами | 01 | Канал 0 счета

Подчиненный | 02 | Канал 1 адрес

| 03 | Канал 1 счета

| 04 | Канал 2 адреса

| 05 | Канал 2 счета

| 06 | Канал 3 адреса

| 07 | Канал 3 счета

--------------+---------+------------------

DMA 2 | C0 | Канал 4 адреса

с 16 битами | C2 | Канал 4 счета

Ведущий | C4 | Канал 5 адреса

| C6 | Канал 5 счета

| C8 | Канал 6 адреса

| CA | Канал 6 счета

| CC | Канал 7 адреса

| CE | Канал 7 счета

  

Адреса портов для регистров управления

 

Адрес | Операция| Функция

DMAC1 DMAC2 | |

------------+---------+-----------------------------------

0A D4 | Запись | регистр маски

0B D6 | Запись | регистр режима

0C D8 | Запись | регистр сброс байта flip-flop

  

Адреса портов для младших регистров страницы

 

Адрес | Функция

--------+-----------------------------------

81 | 2 Канал DMA с 8 битами

82 | 3 Канал DMA с 8 битами

83 | 1 Канал DMA с 8 битами

87 | 0 Канал DMA с 8 битами

89 | 6 Канал DMA с 16 битами

8A | 7 Канал DMA с 16 битами

8B | 5 Канал DMA с 16 битами

  

Бита регистра режима

 

БИТ | Функция

---------+----------------------------------

Биты 7:6 | Биты выбора Режима

00 | Выбранный Режим запроса

01 | Одиночный выбранный режим

10 | Выбранный блочный режим

11 | Каскадный выбранный режим

---------+----------------------------------

Бит 5 | Бит приращения / декремента Адреса

1 | Выбранный Декремент адреса

0 | Выбранное Приращение адреса

---------+----------------------------------

Бит 4 | Авто инициализация

1 | Автоинициализация включена

0 | Одиночный

---------+----------------------------------

Биты 3:2 | Биты Пересылки

00 | Проверите пересылку

01 | Запишите пересылку ( К памяти )

10 | Читайте пересылку ( Из памяти )

11 | Запрещенный

** | Игнорируется если биты 7:6 = 11

---------+----------------------------------

Биты 1:0 | Биты выбора Канала

00 | Выберите канал 0 (4)

01 | Выберите канал 1 (5)

10 | Выберите канал 2 (6)

11 | Выберите канал 3 (7)

 

 


Биты маски записи

 

БИТ | Функция

----------+-----------------------------------

Биты 7:3 | Неиспользуемый ( Набор к 0 )

|

Бит 2 | Установить/сбросить бит маски

1 | Установить бит маски ( Отключите канал )

0 | Сбросить бит маски ( Доступен канал )

----------+------------------------------------

Биты 1:0 | Биты выбора Канала

00 | канал 0 (4)

01 | канал 1 (5)

10 | канал 2 (6)

11 | канал 3 (7)

 

 

DMAC2 используется для работы с 16 битами и DMAC1 используется для

работы с 8 битами. Вот пример программирования DMA:

 

1) Вычислите абсолютный линейный адрес вашего буфера

LinearAddr = MK_SEG( Buf ) * 16L + MK_OFF ( Buf );

 

2) Отключите канал DMA звуковой платы установкой бита маски

outp(MaskPort, 1 + ( DMAChannel % 4 ));

 

3) Очистите указатель байта flip-flop

outp(ClrPort, DMAChannel );

 

4) Запишите режим DMA для пересылки

Биты выбора режима должны устанавливаться в 00h для режима запроса.

Адрес бита +/- должен устанавливаться в 0 для приращения адреса.

Бит автоинициализации должен устанавливаться соответственно.

Биты пересылки должны устанавливаться в 10h для воспроизведения и

01h для записи. Выбор канала должен устанавливаться так же как и на

канал DMA звуковой платы.

outp(ModePort, Mode + ( DMAChannel % 4 ));

 

Некоторые часто используемые режимы:

48h + Канал - одиночный цикл воспроизведение

58h + Канал - автоинициализируемое воспроизведение

44h + Канал - запись одиночного цикла

54h + Канал - автоинициализируемая запись

 

5) Запишите смещение буфера, младший байт затем старший байт. Для

шестнадцати разрядных данных, смещение должно быть в словах от начала

128k-байтной страницы, для 8-битных от 64K. Самый простой метод для

вычисления смещения с 16 битами - это разделить линейный адрес на

два перед вычислением смещения.

 

#define lo(value) (unsigned char)((value) & 0x00FF)

#define hi(value) (unsigned char)((value) >> 8)

 

if ( SixteenBit==1 )

BufOffset= ( LinearAddr / 2 ) % 65536;

else BufOffset= LinearAddr % 65536;

outp(BaseAddrPort, lo(BufOffset));

outp(BaseAddrPort, hi(BufOffset));

 

6) Запишите длину пересылки в соответствующий порт счета, младший

байт затем старший байт. Для пересылки с 8 битами, запишите

длину в байтах минус единица. Для пересылки с 16 битами, запишите

номер длину в словах минус единица.

 

if ( SixteenBit==1 )

TransferLength/=2;

outp(CountPort, lo(TransferLength-1));

outp(CountPort, hi(TransferLength-1));

 

7) Запишите страницу буфера в регистр страницы DMA.

outp(PagePort, ( LinearAddr / 65536));

 

8) Включите DMA звуковой платы очистив соответствующий бит маски

outp(MaskPort, DMAChannel % 4);

 

Пример :

int MaskPort, ClrPort, ModePort, ModeDMA, CountPort, PagePort,

BaseAddrPort;

int pageports[4]={ 0x87, 0x83, 0x81, 0x82 };

 

MaskPort=0x0A; ClrPort=0xC; ModePort=0xB;

ModeDMA=0x48+DMAChannel;

CountPort=1+DMAChannel*2;

BaseAddrPort=DMAChannel*2;

PagePort=pageports[DMAChannel];

 

outportb(MaskPort, 4 + DMAChannel);

outportb(ClrPort, DMAChannel );

outportb(ModePort, ModeDMA );

outportb(BaseAddrPort,lo(aligned_physical));

outportb(BaseAddrPort,hi(aligned_physical));

outportb(PagePort,(unsigned char)((aligned_physical>>16)&0xFF));

outportb(CountPort,lo(len-1));

outportb(CountPort,hi(len-1));

outportb(MaskPort, DMAChannel );

 

 


+---------------------------+------------------------------------------------

| Установка частоты выборки |

+===========================+

 

Для версии Sound Blaster ниже 4.00 установка частоты выборки выполняется

посылкой DSP команды 40h. При этом частота преобразуется к константе времени

по формуле:

4KHz - > 23 KHz:

Time Constant = 256 - (1,000,000 / sampling rate)

= 256 - (1,000,000 / 8,000 )

= 131

 

4KHz - > 44 KHz:

Time Constant = (MSByte of) 65536 - (256,000,000 / sampling rate)

= (MSByte of) 65536 - (256,000,000 / 44,100)

= (MSByte of) 59731

= (MSByte of) 0E953h

= 0E9h

 

void pascal RateSB

( unsigned int rate )

{

unsigned char tc;

 

if ( MaxFrequency==0 )

{

if ( rate<5000 ) rate=5000;

if ( rate>22528 ) rate=22528;

tc = (unsigned char)(256 - (1000000/rate));

}

else

{

if ( rate<5000 ) rate=5000;

if ( rate>45056 ) rate=45056;

tc = (unsigned char)(hi((unsigned int)(65536-(256000000L/rate))));

}

WriteSB(TIME_CONSTANT);

WriteSB(tc);

}

 

В отличие от этого SB16 программируется фактической частотой выборки.

Команда 41h используется для воспроизведения, а 42h используется для записи.

if ( Play==1 )

WriteSB ( 0x41 );

else WriteSB ( 0x42 );

WriteSB ( hi( frequency ) );

WriteSB ( lo( frequency ) );

 


+---------------------------------------+------------------------------------

| Алгоритм цифрового ввода/вывода звука |

+=======================================+

 

Чтобы записывать или воспроизводить звук, вы должны использовать следующую

последовательность:

 

1) Распределите буфер который не пересекает границу 64 Kb

2) Установите программу обработки прерывания.

3) Запрограммируйте контроллер DMA для фоновой пересылки

4) Установите частоту выборки

5) Запишите команду I/O в DSP

6) Запишите режим пересылки I/O в DSP

7) Запишите размер блока в DSP ( Младший байт/Старший байт )

 

После этого сразу начнется запись или воспроизведение звука.

 

Выделение памяти под буфер DMA:

 

data=(char far *)farmalloc(131000L);

if ( data==NULL )

{

printf("Нет места под буфер DMA\n");

return 0;

}

physical=((unsigned long)FP_OFF(data))+(((unsigned long)FP_SEG(data))<<4);

aligned_physical=physical+0x0FFFFL;

aligned_physical&=0xF0000L;

aligned=MK_FP((unsigned )((aligned_physical >> 4) & 0xFFFF),0);

 

 Ниже приведены примеры последовательностей для программирования SB

с помощью DMA.

Нормальная частота, воспроизведение:

 

1) Записать D1h в 2xCh

2) Установить обработчик прерывания

3) Записать 40h в 2xCh

4) Записать константы времени в 2xCh

5) Запрограммировать DMA

6) Записать 14h в 2xCh

7) Записать длину выборки

8) Обслуживать прерывания, до окончания выборки

9) Восстановить старый обработчик

10) Записать D3h в 2xCh

 

При этом можно записывать любые команды в DSP, пока идет воспроизведение.

 

Повышенная частота, воспроизведение:

 

1) Записать D1h в 2xCh

2) Установить обработчик прерывания

3) Записать 40h в 2xCh

4) Записать константы времени в 2xCh

5) Запрограммировать DMA

6) Записать 48h в 2xCh

7) Записать длину выборки

8) Записать 91h в 2xCh

9) Обслуживать прерывания, до окончания выборки

10) Восстановить старый обработчик

11) Записать D3h в 2xCh

 

Нормальная частота, запись звука:

 

1) Установить обработчик прерывания

2) Записать 40h в 2xCh

3) Записать константы времени в 2xCh

4) Запрограммировать DMA

5) Записать 24h в 2xCh

6) Записать длину выборки

7) Обслуживать прерывания, до окончания выборки

8) Восстановить старый обработчик

 

При этом можно посылать любые команды в DSP, пока идет запись.

 

Повышенная частота, запись:

 

1) Установить обработчик прерывания

2) Записать 40h в 2xCh

3) Записать константы времени в 2xCh

4) Запрограммировать DMA

5) Записать 48h в 2xCh

6) Записать длину выборки

7) Записать 99h в 2xCh

8) Обслуживать прерывания, до окончания выборки

9) Восстановить старый обработчик

 


+------------------------------------+--------------------------------------

| Конец цифрового ввода/вывода звука |

+====================================+

 

Когда пересылка закончена генерируется прерывание. Фактический номер

прерывания зависит от установки IRQ на плате Sound Blaster:

 

IRQ | Прерывание

-----+------------

2 | 0Ah

3 | 0Bh

5 | 0Dh

7 | 0Fh

 

 Для обслуживания прерывания необходимо выполнить:

 

1) подтвердите прием прерывания от DSP прочитав порт (2xEh) один раз для

8-битного звука, или порт 2xF для 16-битного звука.

2) Вывод следующего буфера, если есть.

3) Выведите значение 20h ( EOI ) в порт контроллера прерывания 20h,

а если IRQ8-15(прерывания 70h-77h), то записать 20h в A0h.

 

Установка прерывания :

 

DMA_complete = 0;

disable();

OldIRQ = getvect(0x08 + SbIRQ);

setvect(0x08 + SbIRQ,SBHandler);

enable();

 

Обработчик прерывания :

 

static void far interrupt SBHandler( void )

{

enable();

DMA_complete = 1;

 

// подтведить

inportb(baseAddrSB+0xE);

outportb(0x20,0x20);

}

 

Инициализация обработчика :

 

DMA_complete = 0;

im = inportb(0x21);

tm = ~(1 << SbIRQ);

outportb(0x21,im & tm);

enable();

 

Сброс обработчика :

 

disable();

setvect(0x08 + SbIRQ,OldIRQ);

i = inportb(0x21);

outportb(0x21, i | (1 << SbIRQ));

enable();

 

Воспроизведение файла выборки:

 

f = fopen(argv[1],"rb");

raw = ( char far * ) farmalloc(32000L);

if ( f == 0 || raw==0 )

{

printf("Не могу открыть файл выборки - %s\n",argv[1]);

printf("Нет памяти\n",argv[1]);

ResetSB();

return;

}

 

printf("Воспроизведение выборки ...\n");

WriteSB(ON_SOUND_SB);

RateSB(22222);

 

len=fread(raw,1,32000,f);

while ( 1 )

{

if ( len==0 ) break;

PlaySB(raw,len);

len=fread(raw,1,32000,f);

while ( StatePlaySB()==0 )

if ( kbhit() ) { getch(); goto Fin; }

}

 

Fin:

if ( f!=0 ) fclose(f);

if ( raw!=0 ) farfree(raw);

ResetSB();

 

 


+-------------+-------------------------------------------------------------

| Стерео звук |

+=============+

 

При воспроизведении стерео звуков необходимо посылать 2 байта DSP, первый

для левого канала, второй для правого. Необходимо так же указать SB,

что вы воспроизводите стерео звук, через регистры миксера.

  

+----------------------+----------------------------------------------------

| Миксер Sound Blaster |

+======================+

 

Ниже приведена информация для SbPro.

Порт 2x4h - индексный порт миксера, 2x5h - порт данных (чтения/записи).

 

void pascal WriteMixerSB

( char index, char val )

{

outportb(baseAddrSB+4,index);

outportb(baseAddrSB+5,val);

}

  

char pascal ReadMixerSB

( char index )

{

outportb(baseAddrSB+4,index);

return inportb(baseAddrSB+5);

}

 

 Регистр Сброса Данных используется для инициализации миксера. Установите

этот регистр в 0 перед изменением любого из других регистров миксера.

 

void pascal ResetMixerSB

( void )

{

WriteMixerSB(0,0); // RESET

}

 

Регистр записи определяет источник звука и тип фильтра.

 

Индекс = 0Ch

 

7 6 5 4 3 2 1 0

--------+-------+---+---+----

+---+---+ +-+-+

+---+ |

| |

В Фильтре ADC Источник

000 - Низкие 00 - Микрофон 1

001 - Высокие 01 - CD

010 - Нет Фильтра 10 - Микрофон 2

11 - Линейный вход

 

#define SOURCE_MIC1 0

#define SOURCE_CD 1

#define SOURCE_MIC2 2

#define SOURCE_LINE 3

  

void pascal InputMixerSB

( char sou, char filtr )

{

char val;

val=(sou<<1)&0x6;

val|=(filtr<<3)&0x38;

WriteMixerSB(0xC,val);

}

 

 


Регистр воспроизведения  служит для установки фильтра и стерео звука.

 

Индекс = 0Eh

 

7 6 5 4 3 2 1 0

--------+---------------+----

| |

| |

0 - Использовать фильтр 0 - моно

1 - Без фильтра 1 - Stereo

 

 

#define MONO 0

#define STEREO 1

 

#define USE_FILTER 0

#define BYPASS_FILTER 1

 

void pascal OutputMixerSB

( char st, char filtr )

{

char val;

val=(st==1)?2:0;

val|=(filtr==1)?0x20:0;

WriteMixerSB(0xE,val);

}

 

Регистр общей громкости:

 

Индекс = 22h

 

7 6 5 4 3 2 1 0

+-----------+---+-----------+

+-----+-----+ +-----+-----+

| |

Громкость Громкость

Лево Право

 

void pascal MasterVolumeSB

( char left, char right )

{

char val;

val=right&0xf;

val|=(left<<4)&0xf0;

WriteMixerSB(0x22,val);

}

 

Регистр громкости DSP:

 

Индекс = 04h

 

7 6 5 4 3 2 1 0

+-----------+---+-----------+

+-----+-----+ +-----+-----+

| |

Громкость Громкость

Лево Право

 

void pascal VoiceVolumeSB

( char left, char right )

{

char val;

val=right&0xf;

val|=(left<<4)&0xf0;

WriteMixerSB(0x04,val);

}

  

Регистр громкости FM синтезатора:

 

Индекс= 26h

 

7 6 5 4 3 2 1 0

+-----------+---+-----------+

+-----+-----+ +-----+-----+

| |

Громкость Громкость

Лево Право

 

void pascal FMVolumeSB

( char left, char right )

{

char val;

val=right&0xf;

val|=(left<<4)&0xf0;

WriteMixerSB(0x26,val);

}

 

 


Регистр громкости CD:

 

Индекс = 28h

 

7 6 5 4 3 2 1 0

+-----------+---+-----------+

+-----+-----+ +-----+-----+

| |

Громкость Громкость

Лево Право

 

void pascal CDVolumeSB

( char left, char right )

{

char val;

val=right&0xf;

val|=(left<<4)&0xf0;

WriteMixerSB(0x28,val);

}

  

Регистр громкости линейного входа:

 

Индекс = 2Eh

 

7 6 5 4 3 2 1 0

+-----------+---+-----------+

+-----+-----+ +-----+-----+

| |

Громкость Громкость

Лево Право

 

void pascal LineVolumeSB

( char left, char right )

{

char val;

val=right&0xf;

val|=(left<<4)&0xf0;

WriteMixerSB(0x2E,val);

}

 

Регистр громкости микрофона:

 

Индекс = 0Ah

 

7 6 5 4 3 2 1 0

--------------------+-------+

+---+---+

|

Громкость микрофона.

 

void pascal MicVolumeSB

( char vol )

{

char val;

val=vol&0x7;

WriteMixerSB(0xA,val);

}

  

+------------+--------------------------------------------------------------

| Примечание:|

+============+

 

Данный документ составлен Анисимовым С.Ю. 08/1995. г. К-Чепецк,

Кировской обл. Россия. v1.( и последняя )

Данными для составления этого документа послужила информация

из различных источников. Поэтому автор не несет ответственность

за неверную информацию, и за повреждения техники и тел при

использовании этого документа.

С наилучшими пожеланиями, для всех любителей программировать Sound Blaster !

Vale ! 

 

 

Взято с Vingrad.ru https://forum.vingrad.ru