Difference between revisions of "Sound/ru"

From KolibriOS wiki
Jump to navigation Jump to search
m (Improved syntax highlighting)
m (Some additional info)
Line 28: Line 28:
 
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
+
== 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: Библиотеки]]

Revision as of 11:29, 14 June 2012

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

К сожалению какой либо внятной документации по Infinity нет, есть только исходники и файлы SDK.

Звуковая система 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

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