Difference between revisions of "Sound/ru"

From KolibriOS wiki
Jump to navigation Jump to search
(Created page with "Изначально Колибри унаследовала от Менуэт только звуковой драйвер для ''SoundBlaster'', встроенный в я...")
 
 
(6 intermediate revisions by 3 users not shown)
Line 2: Line 2:
  
 
К сожалению какой либо внятной документации по '''Infinity''' нет, есть только исходники и файлы SDK.
 
К сожалению какой либо внятной документации по '''Infinity''' нет, есть только исходники и файлы SDK.
 +
См. этот комментарий http://board.kolibrios.org/viewtopic.php?p=51462#p51462
  
 
Звуковая система '''Infinity''' содержит следующие сервисы:
 
Звуковая система '''Infinity''' содержит следующие сервисы:
  SRV_GETVERSION      equ 0
+
<syntaxhighlight lang="asm">
  SND_CREATE_BUFF      equ 1
+
SRV_GETVERSION      equ 0
  SND_DESTROY_BUFF    equ 2
+
SND_CREATE_BUFF      equ 1
  SND_SETFORMAT        equ 3
+
SND_DESTROY_BUFF    equ 2
  SND_GETFORMAT        equ 4
+
SND_SETFORMAT        equ 3
  SND_RESET            equ 5
+
SND_GETFORMAT        equ 4
  SND_SETPOS          equ 6
+
SND_RESET            equ 5
  SND_GETPOS          equ 7
+
SND_SETPOS          equ 6
  SND_SETBUFF          equ 8
+
SND_GETPOS          equ 7
  SND_OUT              equ 9
+
SND_SETBUFF          equ 8
  SND_PLAY            equ 10
+
SND_OUT              equ 9
  SND_STOP            equ 11
+
SND_PLAY            equ 10
  SND_SETVOLUME        equ 12
+
SND_STOP            equ 11
  SND_GETVOLUME        equ 13
+
SND_SETVOLUME        equ 12
  SND_SETPAN          equ 14
+
SND_GETVOLUME        equ 13
  SND_GETPAN          equ 15
+
SND_SETPAN          equ 14
  SND_GETBUFFSIZE      equ 16
+
SND_GETPAN          equ 15
  SND_GETFREESPACE    equ 17
+
SND_GETBUFFSIZE      equ 16
  SND_SETTIMEBASE      equ 18
+
SND_GETFREESPACE    equ 17
  SND_GETTIMESTAMP    equ 19
+
SND_SETTIMEBASE      equ 18
 +
SND_GETTIMESTAMP    equ 19
 +
</syntaxhighlight>
 +
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 библиотеки]:
+
== init.asm ==
 +
<syntaxhighlight lang="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
 +
</syntaxhighlight>
 +
== setbuf.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
 +
; int _stdcall  PlayBuffer(SNDBUF hBuff,unsigned int flags);
 +
_PlayBuffer@8:      ;str:dword,flags:dword
 +
</syntaxhighlight>
 +
== sndgetfmt.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  GetFormat(SNDBUF hBuff, unsigned int *format);
 +
_GetFormat@8:        ;str:dword, p_fmt:dword
 +
</syntaxhighlight>
 +
== sndgetmvol.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  GetMasterVol(int* vol);
 +
proc _GetMasterVol@4 stdcall, pvol:dword
 +
proc _GetDevInfo@8  stdcall, hSrv:dword, p_info:dword
 +
</syntaxhighlight>
 +
== sndgetpan.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  GetPan(SNDBUF hBuff, int *pan);
 +
_GetPan@8:          ;str:dword, p_pan:dword
 +
</syntaxhighlight>
 +
Возвращает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где -10000 - тишина в правом канале 10000 - тишина в левом канале 0 - нормальный баланс каналов
 +
== sndgetpos.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  GetBufferPos(SNDBUF hBuff, int *offset);
 +
_GetBufferPos@8:    ;str:dword, p_pos:dword
 +
</syntaxhighlight>
 +
== sndgetsize.asm ==
 +
<syntaxhighlight lang="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
 +
</syntaxhighlight>
 +
== sndgetvol.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  GetVolume(SNDBUF hBuff, int *left, int *right);
 +
proc _GetVolume@12  stdcall, str:dword, pleft:dword,pright:dword
 +
</syntaxhighlight>
 +
== sndout.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  WaveOut(SNDBUF hBuff,void *buff, int size);
 +
_WaveOut@12:        ;str:dword, src:dword, size:dword
 +
</syntaxhighlight>
 +
== sndreset.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  ResetBuffer(SNDBUF hBuff, unsigned int flags);
 +
_ResetBuffer@8:      ;str:dword, flags:dword
 +
</syntaxhighlight>
 +
== sndsetfmt.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  SetFormat(SNDBUF hBuff, unsigned int format);
 +
_SetFormat@8:        ;str:dword, fmt:dword
 +
</syntaxhighlight>
 +
Устанавливает новый формат звукового буфера. Применимо для PCM_OUT и PCM_STATIC буферов.
 +
== sndsetmvol.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  SetMasterVol(int vol);
 +
_SetMasterVol@4:    ;vol:dword
 +
</syntaxhighlight>
 +
== sndsetpan.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  SetPan(SNDBUF hBuff, int pan);
 +
_SetPan@8:          ;str:dword, pan:dword
 +
</syntaxhighlight>
 +
Устанавливает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где
 +
-10000 - тишина в правом канале
 +
10000 - тишина в левом канале
 +
0 - нормальный баланс каналов
 +
== sndsetpos.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  SetBufferPos(SNDBUF hBuff, int offset);
 +
_SetBufferPos@8:    ;str:dword, offs:dword
 +
</syntaxhighlight>
 +
Устанавливает начальную позицию для статического звукового буфера.
 +
== sndsetvol.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  SetVolume(SNDBUF hBuff, int left, int right);
 +
_SetVolume@12:      ;str:dword, lvol:dword,rvol:dword
 +
</syntaxhighlight>
 +
Устанавливает уровень громкости для правого и левого каналов. Уровень задаётся как ослабление сигнала в сотых долях децибела в диапазоне 0 - -10000, где
 +
0 - максимальная громкость
 +
-10000 (-100dB) - полная тишина
 +
== stopbuf.asm ==
 +
<syntaxhighlight lang="asm">
 +
; int _stdcall  StopBuffer(SNDBUF hBuff);
 +
_StopBuffer@4:      ;str:dword
 +
</syntaxhighlight>
 +
== wavhdr.asm ==
 +
<syntaxhighlight lang="asm">
 +
proc _test_wav@4    stdcall, hdr:dword
 +
</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>
 +
 
 +
=== Применение ===
 +
 
 +
# Статический буфер: простая звуковая сигнализация, озвучка интерфейса и т.п. Позволяет одновременно использовать звуковые данные в разных форматах.
 +
# Потоковый буфер: различные аудиоплееры. Программа загружает большие объёмы звуковых данных из сети, накопителей или генерирует их в реальном времени.
 +
# Кольцевой буфер: игры и другие приложения с повышенными требованиями к синхронности аудио- и видеоряда.
  
1) init.asm
+
[[Category: Библиотеки]]
  _InitSound@4:       ;p_ver:dword
 
  _CreateBuffer@12:    ;format:dword,size:dword,p_str:dword
 
  _DestroyBuffer@4:    ;str:dword
 
2) setbuf.asm
 
  _SetBuffer@16:      ;str:dword, src:dword, offs:dword, size:dword
 
  _PlayBuffer@8:      ;str:dword,flags:dword
 
3) sndgetfmt.asm
 
  _GetFormat@8:        ;str:dword, p_fmt:dword
 
4) sndgetmvol.asm
 
  proc _GetMasterVol@4 stdcall, pvol:dword
 
  proc _GetDevInfo@8  stdcall, hSrv:dword, p_info:dword
 
5) sndgetpan.asm
 
  _GetPan@8:          ;str:dword, p_pan:dword
 
6) sndgetpos.asm
 
  _GetBufferPos@8:    ;str:dword, p_pos:dword
 
7) sndgetsize.asm
 
  _GetBufferSize@8:    ;str:dword, p_size:dword
 
  _GetBufferFree@8:    ;str:dword, p_free:dword
 
8) sndgetvol.asm
 
  proc _GetVolume@12  stdcall, str:dword, pleft:dword,pright:dword
 
9) sndout.asm
 
  _WaveOut@12:        ;str:dword, src:dword, size:dword
 
10) sndreset.asm
 
  _ResetBuffer@8:      ;str:dword, flags:dword
 
11) sndsetfmt.asm
 
  _SetFormat@8:        ;str:dword, fmt:dword
 
12) sndsetmvol.asm
 
  _SetMasterVol@4:    ;vol:dword
 
13) sndsetpan.asm
 
  _SetPan@8:          ;str:dword, pan:dword
 
14) sndsetpos.asm
 
  _SetBufferPos@8:    ;str:dword, offs:dword
 
15) sndsetvol.asm
 
  _SetVolume@12:      ;str:dword, lvol:dword,rvol:dword
 
16) stopbuf.asm
 
  _StopBuffer@4:      ;str:dword
 
17) wavhdr.asm
 
  proc _test_wav@4    stdcall, hdr:dword
 

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);


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