Sound/ru: Difference between revisions

From KolibriOS wiki
Jump to navigation Jump to search
m (Improved syntax highlighting)
No edit summary
 
(2 intermediate revisions by 2 users not shown)
Line 2: Line 2:


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


Звуковая система '''Infinity''' содержит следующие сервисы:
Звуковая система '''Infinity''' содержит следующие сервисы:
Line 28: Line 29:
SDK содержит следующие вспомогательные [http://websvn.kolibrios.org/listing.php?repname=Kolibri+OS&path=%2Fprograms%2Fdevelop%2Fsdk%2Ftrunk%2Fsound%2Fsrc%2F&#a375d81500982fc566688f871656e47fa библиотеки]:
SDK содержит следующие вспомогательные [http://websvn.kolibrios.org/listing.php?repname=Kolibri+OS&path=%2Fprograms%2Fdevelop%2Fsdk%2Ftrunk%2Fsound%2Fsrc%2F&#a375d81500982fc566688f871656e47fa библиотеки]:


1) init.asm
== init.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  InitSound(int *version);
_InitSound@4:        ;p_ver:dword
_InitSound@4:        ;p_ver:dword
; int _stdcall  CreateBuffer(unsigned int format,int size,SNDBUF *buf);
_CreateBuffer@12:    ;format:dword,size:dword,p_str:dword
_CreateBuffer@12:    ;format:dword,size:dword,p_str:dword
; int _stdcall  DestroyBuffer(SNDBUF hBuff);
_DestroyBuffer@4:    ;str:dword
_DestroyBuffer@4:    ;str:dword
</syntaxhighlight>
</syntaxhighlight>
2) setbuf.asm
== setbuf.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  SetBuffer(SNDBUF hBuff,void* buff, int offs, int size);
_SetBuffer@16:      ;str:dword, src:dword, offs:dword, size:dword
_SetBuffer@16:      ;str:dword, src:dword, offs:dword, size:dword
; int _stdcall  PlayBuffer(SNDBUF hBuff,unsigned int flags);
_PlayBuffer@8:      ;str:dword,flags:dword
_PlayBuffer@8:      ;str:dword,flags:dword
</syntaxhighlight>
</syntaxhighlight>
3) sndgetfmt.asm
== sndgetfmt.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  GetFormat(SNDBUF hBuff, unsigned int *format);
_GetFormat@8:        ;str:dword, p_fmt:dword
_GetFormat@8:        ;str:dword, p_fmt:dword
</syntaxhighlight>
</syntaxhighlight>
4) sndgetmvol.asm
== sndgetmvol.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  GetMasterVol(int* vol);
proc _GetMasterVol@4 stdcall, pvol:dword
proc _GetMasterVol@4 stdcall, pvol:dword
proc _GetDevInfo@8  stdcall, hSrv:dword, p_info:dword
proc _GetDevInfo@8  stdcall, hSrv:dword, p_info:dword
</syntaxhighlight>
</syntaxhighlight>
5) sndgetpan.asm
== sndgetpan.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  GetPan(SNDBUF hBuff, int *pan);
_GetPan@8:          ;str:dword, p_pan:dword
_GetPan@8:          ;str:dword, p_pan:dword
</syntaxhighlight>
</syntaxhighlight>
6) sndgetpos.asm
Возвращает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где -10000 - тишина в правом канале 10000 - тишина в левом канале 0 - нормальный баланс каналов
== sndgetpos.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  GetBufferPos(SNDBUF hBuff, int *offset);
_GetBufferPos@8:    ;str:dword, p_pos:dword
_GetBufferPos@8:    ;str:dword, p_pos:dword
</syntaxhighlight>
</syntaxhighlight>
7) sndgetsize.asm
== sndgetsize.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  GetBufferSize(SNDBUF hBuff, int *size);
_GetBufferSize@8:    ;str:dword, p_size:dword
_GetBufferSize@8:    ;str:dword, p_size:dword
; int _stdcall  GetBufferFree(SNDBUF hBuff, int *free);
_GetBufferFree@8:    ;str:dword, p_free:dword
_GetBufferFree@8:    ;str:dword, p_free:dword
</syntaxhighlight>
</syntaxhighlight>
8) sndgetvol.asm
== sndgetvol.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  GetVolume(SNDBUF hBuff, int *left, int *right);
proc _GetVolume@12  stdcall, str:dword, pleft:dword,pright:dword
proc _GetVolume@12  stdcall, str:dword, pleft:dword,pright:dword
</syntaxhighlight>
</syntaxhighlight>
9) sndout.asm
== sndout.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  WaveOut(SNDBUF hBuff,void *buff, int size);
_WaveOut@12:        ;str:dword, src:dword, size:dword
_WaveOut@12:        ;str:dword, src:dword, size:dword
</syntaxhighlight>
</syntaxhighlight>
10) sndreset.asm
== sndreset.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  ResetBuffer(SNDBUF hBuff, unsigned int flags);
_ResetBuffer@8:      ;str:dword, flags:dword
_ResetBuffer@8:      ;str:dword, flags:dword
</syntaxhighlight>
</syntaxhighlight>
11) sndsetfmt.asm
== sndsetfmt.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  SetFormat(SNDBUF hBuff, unsigned int format);
_SetFormat@8:        ;str:dword, fmt:dword
_SetFormat@8:        ;str:dword, fmt:dword
</syntaxhighlight>
</syntaxhighlight>
12) sndsetmvol.asm
Устанавливает новый формат звукового буфера. Применимо для PCM_OUT и PCM_STATIC буферов.
== sndsetmvol.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  SetMasterVol(int vol);
_SetMasterVol@4:    ;vol:dword
_SetMasterVol@4:    ;vol:dword
</syntaxhighlight>
</syntaxhighlight>
13) sndsetpan.asm
== sndsetpan.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  SetPan(SNDBUF hBuff, int pan);
_SetPan@8:          ;str:dword, pan:dword
_SetPan@8:          ;str:dword, pan:dword
</syntaxhighlight>
</syntaxhighlight>
14) sndsetpos.asm
Устанавливает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где
-10000 - тишина в правом канале
10000 - тишина в левом канале
0 - нормальный баланс каналов
== sndsetpos.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  SetBufferPos(SNDBUF hBuff, int offset);
_SetBufferPos@8:    ;str:dword, offs:dword
_SetBufferPos@8:    ;str:dword, offs:dword
</syntaxhighlight>
</syntaxhighlight>
15) sndsetvol.asm
Устанавливает начальную позицию для статического звукового буфера.
== sndsetvol.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  SetVolume(SNDBUF hBuff, int left, int right);
_SetVolume@12:      ;str:dword, lvol:dword,rvol:dword
_SetVolume@12:      ;str:dword, lvol:dword,rvol:dword
</syntaxhighlight>
</syntaxhighlight>
16) stopbuf.asm
Устанавливает уровень громкости для правого и левого каналов. Уровень задаётся как ослабление сигнала в сотых долях децибела в диапазоне 0 - -10000, где
0 - максимальная громкость
-10000 (-100dB) - полная тишина
== stopbuf.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
; int _stdcall  StopBuffer(SNDBUF hBuff);
_StopBuffer@4:      ;str:dword
_StopBuffer@4:      ;str:dword
</syntaxhighlight>
</syntaxhighlight>
17) wavhdr.asm
== wavhdr.asm ==
<syntaxhighlight lang="asm">
<syntaxhighlight lang="asm">
proc _test_wav@4    stdcall, hdr:dword
proc _test_wav@4    stdcall, hdr:dword
</syntaxhighlight>
</syntaxhighlight>
= Примеры =
== Инициализация ==
<syntaxhighlight lang="c">
#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;
    }
</syntaxhighlight>
== Звуковые буферы ==
Создаём звуковой буфер.
Есть три вида буферов - статические (PCM_STATIC), потоковые (PCM_OUT) и кольцевые (PCM_RING). Самый простой для программирования - потоковый. Статический буфер не сильно отличается от буфера в DirectSound. SetBuffer заполняет буфер, GetBufferPos и SetBufferPos получают и устанавливают текущую позицию в буфере. Кольцевой буфер позволяет выводить звук с минимальной задержкой. Это аналог Direct Sound буфера с событиями, поделённого на две части.
<syntaxhighlight lang="c">
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);
Для статического буфера размером 1Mб
    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;
    };
</syntaxhighlight>
=== Применение ===
# Статический буфер: простая звуковая сигнализация, озвучка интерфейса и т.п. Позволяет одновременно использовать звуковые данные в разных форматах.
# Потоковый буфер: различные аудиоплееры. Программа загружает большие объёмы звуковых данных из сети, накопителей или генерирует их в реальном времени.
# Кольцевой буфер: игры и другие приложения с повышенными требованиями к синхронности аудио- и видеоряда.


[[Category: Библиотеки]]
[[Category: Библиотеки]]

Latest revision as of 12:46, 18 September 2013

Изначально Колибри унаследовала от Менуэт только звуковой драйвер для 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);


Для статического буфера размером 1Mб
    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. Кольцевой буфер: игры и другие приложения с повышенными требованиями к синхронности аудио- и видеоряда.