Sound/ru

From KolibriOS wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Изначально Колибри унаследовала от Менуэт только звуковой драйвер для SoundBlaster, встроенный в ядро. Позже в (2005-2006) была написана полноценная звуковая подсистема Infinity, автор Сергей Семёнов aka Serge.

К сожалению какой либо внятной документации по Infinity нет, есть только исходники и файлы SDK. См. этот комментарий http://board.kolibrios.org/viewtopic.php?p=51462#p51462

Звуковая система Infinity содержит следующие сервисы:

SRV_GETVERSION       equ 0
SND_CREATE_BUFF      equ 1
SND_DESTROY_BUFF     equ 2
SND_SETFORMAT        equ 3
SND_GETFORMAT        equ 4
SND_RESET            equ 5
SND_SETPOS           equ 6
SND_GETPOS           equ 7
SND_SETBUFF          equ 8
SND_OUT              equ 9
SND_PLAY             equ 10
SND_STOP             equ 11
SND_SETVOLUME        equ 12
SND_GETVOLUME        equ 13
SND_SETPAN           equ 14
SND_GETPAN           equ 15
SND_GETBUFFSIZE      equ 16
SND_GETFREESPACE     equ 17
SND_SETTIMEBASE      equ 18
SND_GETTIMESTAMP     equ 19

SDK содержит следующие вспомогательные библиотеки:

init.asm

; int _stdcall  InitSound(int *version);
_InitSound@4:        ;p_ver:dword
; int _stdcall  CreateBuffer(unsigned int format,int size,SNDBUF *buf);
_CreateBuffer@12:    ;format:dword,size:dword,p_str:dword
; int _stdcall  DestroyBuffer(SNDBUF hBuff);
_DestroyBuffer@4:    ;str:dword

setbuf.asm

; int _stdcall  SetBuffer(SNDBUF hBuff,void* buff, int offs, int size);
_SetBuffer@16:       ;str:dword, src:dword, offs:dword, size:dword
; int _stdcall  PlayBuffer(SNDBUF hBuff,unsigned int flags);
_PlayBuffer@8:       ;str:dword,flags:dword

sndgetfmt.asm

; int _stdcall  GetFormat(SNDBUF hBuff, unsigned int *format);
_GetFormat@8:        ;str:dword, p_fmt:dword

sndgetmvol.asm

; int _stdcall  GetMasterVol(int* vol);
proc _GetMasterVol@4 stdcall, pvol:dword
proc _GetDevInfo@8   stdcall, hSrv:dword, p_info:dword

sndgetpan.asm

; int _stdcall  GetPan(SNDBUF hBuff, int *pan);
_GetPan@8:           ;str:dword, p_pan:dword

Возвращает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где -10000 - тишина в правом канале 10000 - тишина в левом канале 0 - нормальный баланс каналов

sndgetpos.asm

; int _stdcall  GetBufferPos(SNDBUF hBuff, int *offset);
_GetBufferPos@8:     ;str:dword, p_pos:dword

sndgetsize.asm

; int _stdcall  GetBufferSize(SNDBUF hBuff, int *size);
_GetBufferSize@8:    ;str:dword, p_size:dword
; int _stdcall  GetBufferFree(SNDBUF hBuff, int *free);
_GetBufferFree@8:    ;str:dword, p_free:dword

sndgetvol.asm

; int _stdcall  GetVolume(SNDBUF hBuff, int *left, int *right);
proc _GetVolume@12   stdcall, str:dword, pleft:dword,pright:dword

sndout.asm

; int _stdcall  WaveOut(SNDBUF hBuff,void *buff, int size);
_WaveOut@12:         ;str:dword, src:dword, size:dword

sndreset.asm

; int _stdcall  ResetBuffer(SNDBUF hBuff, unsigned int flags);
_ResetBuffer@8:      ;str:dword, flags:dword

sndsetfmt.asm

; int _stdcall  SetFormat(SNDBUF hBuff, unsigned int format);
_SetFormat@8:        ;str:dword, fmt:dword

Устанавливает новый формат звукового буфера. Применимо для PCM_OUT и PCM_STATIC буферов.

sndsetmvol.asm

; int _stdcall  SetMasterVol(int vol);
_SetMasterVol@4:     ;vol:dword

sndsetpan.asm

; int _stdcall  SetPan(SNDBUF hBuff, int pan);
_SetPan@8:           ;str:dword, pan:dword

Устанавливает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где -10000 - тишина в правом канале 10000 - тишина в левом канале 0 - нормальный баланс каналов

sndsetpos.asm

; int _stdcall  SetBufferPos(SNDBUF hBuff, int offset);
_SetBufferPos@8:     ;str:dword, offs:dword

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

sndsetvol.asm

; int _stdcall  SetVolume(SNDBUF hBuff, int left, int right);
_SetVolume@12:       ;str:dword, lvol:dword,rvol:dword

Устанавливает уровень громкости для правого и левого каналов. Уровень задаётся как ослабление сигнала в сотых долях децибела в диапазоне 0 - -10000, где 0 - максимальная громкость -10000 (-100dB) - полная тишина

stopbuf.asm

; int _stdcall  StopBuffer(SNDBUF hBuff);
_StopBuffer@4:       ;str:dword

wavhdr.asm

proc _test_wav@4     stdcall, hdr:dword

Примеры

Инициализация

#include <sound.h>

    int    err;
    int    version =-1;

    if((err = InitSound(&version)) !=0 ){
        goto epic_fail;
    };

    if( (SOUND_VERSION>(version&0xFFFF)) ||
        (SOUND_VERSION<(version >> 16))){
        goto epic_fail;
    }

Звуковые буферы

Создаём звуковой буфер. Есть три вида буферов - статические (PCM_STATIC), потоковые (PCM_OUT) и кольцевые (PCM_RING). Самый простой для программирования - потоковый. Статический буфер не сильно отличается от буфера в DirectSound. SetBuffer заполняет буфер, GetBufferPos и SetBufferPos получают и устанавливают текущую позицию в буфере. Кольцевой буфер позволяет выводить звук с минимальной задержкой. Это аналог Direct Sound буфера с событиями, поделённого на две части.

SNDBUF hBuff;
    void* buffer; //семплы в формате snd_format
    int buffer_size; // размер буфера в байтах

    if((err = CreateBuffer(snd_format|PCM_OUT, 0, &hBuff)) != 0)
    {
        goto epic_fail;
    };
выводим звук
    WaveOut(hBuff,buffer,buffer_size);


Для статического буфера размером 1
    if((err = CreateBuffer(snd_format|PCM_STATIC, 1024*1024, &hBuff)) != 0)
    {
        goto epic_fail;
    };

заполняем буфер
    int offset; // смещение от начала звукового буфера
    SetBuffer(hBuff, buffer, offset, buffer_size);

выводим звук асинхронно - функция возвращает управление немедленно
    if((err = PlayBuffer(hBuff, 0)) !=0 ){
        goto exit_whith_error;
    };
синхронно - поток блокируется пока весь буфер не будет воспроизведён
    if((err = PlayBuffer(hBuff, PLAY_SYNC)) !=0 ){
        goto exit_whith_error;
    };

Применение

  1. Статический буфер: простая звуковая сигнализация, озвучка интерфейса и т.п. Позволяет одновременно использовать звуковые данные в разных форматах.
  2. Потоковый буфер: различные аудиоплееры. Программа загружает большие объёмы звуковых данных из сети, накопителей или генерирует их в реальном времени.
  3. Кольцевой буфер: игры и другие приложения с повышенными требованиями к синхронности аудио- и видеоряда.