Документация по Infinity

Drivers for sound cards
  • Добавил на wiki.kolibrios.org
  • Вечером приду, напишу тебе в аське по поводу Инфинити. У меня есть пару простых примеров, но я не уверен насчет их лицензионной чистоты и блаблабла :) Может, на их основе получится сделать документацию.
  • Так нагляднее.
    Spoiler:

    Code: Select all

    typedef unsigned int SNDBUF;
    
    int _stdcall  InitSound(int *version);
    
    int _stdcall  CreateBuffer(unsigned int format,int size,SNDBUF *buf);
    int _stdcall  DestroyBuffer(SNDBUF hBuff);
    
    int _stdcall  SetFormat(SNDBUF hBuff, unsigned int format);
    int _stdcall  GetFormat(SNDBUF hBuff, unsigned int *format);
    
    int _stdcall  ResetBuffer(SNDBUF hBuff, unsigned int flags);
    int _stdcall  SetBufferPos(SNDBUF hBuff, int offset);
    int _stdcall  GetBufferPos(SNDBUF hBuff, int *offset);
    int _stdcall  GetBufferSize(SNDBUF hBuff, int *size);
    int _stdcall  GetBufferFree(SNDBUF hBuff, int *free);
    
    int _stdcall  SetBuffer(SNDBUF hBuff,void* buff,
                            int offs, int size);
    int _stdcall  WaveOut(SNDBUF hBuff,void *buff, int size);
    int _stdcall  PlayBuffer(SNDBUF hBuff,unsigned int flags);
    int _stdcall  StopBuffer(SNDBUF hBuff);
    
    int _stdcall  SetVolume(SNDBUF hBuff, int left, int right);
    int _stdcall  GetVolume(SNDBUF hBuff, int *left, int *right);
    int _stdcall  SetPan(SNDBUF hBuff, int pan);
    int _stdcall  GetPan(SNDBUF hBuff, int *pan);
    
    int _stdcall  GetMasterVol(int* vol);
    int _stdcall  SetMasterVol(int vol);
    
    int _stdcall  SetTimeBase(SNDBUF hBuff, double base);
    int _stdcall  GetTimeStamp(SNDBUF hBuff, double *stamp);
    
    Инициализируем звук
    Spoiler:

    Code: Select all

    #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 буфера с событиями, поделённого на две части.
    Spoiler:snd_format одна из констант вида PCM_X_Y_Z где
    X- число каналов
    Y- разрядность в битах на канал
    Z- частота в КГц из фиксированного набора 11025Гц, 12000Гц, 16000Гц, 22050Гц, 24000Гц, 32000Гц, 44100Гц, 48000Гц
    Если формат не известен заранее используется константа PCM_ALL. Окончательно формат устанавливается вызовом SetFormat.

    Code: Select all

        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;
        };
    
    Изменение параметров воспроизведения
    Spoiler:SetFormat(hBuff, snd_format);
    Устанавливает новый формат звукового буфера. Применимо для PCM_OUT и PCM_STATIC буферов.
    SetVolume(hBuff, left, right);
    Устанавливает уровень громкости для правого и левого каналов. Уровень задаётся как ослабление сигнала в сотых долях децибела в диапазоне 0 - -10000, где
    0 - максимальная громкость
    -10000 (-100dB) - полная тишина
    SetPan(hBuff, pan);
    Устанавливает баланс левого и правого каналов. Баланс задаётся в сотых долях децибела в диапазоне -10000 - 10000, где
    -10000 - тишина в правом канале
    10000 - тишина в левом канале
    0 - нормальный баланс каналов
    Last edited by Serge on Sun Apr 22, 2012 10:48 pm, edited 6 times in total.
  • Кому как! Мне лично нужно использование в ассемблерных проектах, а таковых нет. А в Сишных вы все и так замечательный междусобойчик устроили.
  • Да, мы Сишники такие вредные.
    Все функции библиотеки написаны ассемблере. Вставить их в любой проект дело нескольких минут.
  • А ниче что последовательность их вызовов тоже надо вылавливать из Сишных исходников? Впрочем ладно забей, раз тебе даже лень на письма в личку отвечать.
  • Mario
    Не лень. Ты открыл тему быстрее чем я успел ответить.
    За 6 лет с вопросами 2 человека обратилось. Ты третий.
  • Serge
    1. Откуда берется buffer_size, когда CreateBuffer с размером 0?
    2. Сколько буферов может создать один поток.
    3. Может ли поток создавать разные типы буферов.
    4. В каких случаях следует применять виды: статические (PCM_STATIC), потоковые (PCM_OUT) и кольцевые (PCM_RING). По каким признакам выбирать вообще? (типичные примеры)
    Вернее я даже представляю как работает кольцевой - там допустим музыка играет в кольце соответственно. Но чем отличаются потоковый и статический не понял.
  • 1. Для PCM_OUT это размер данных, которые необходимо воспроизвести. Данные должны целиком помещаться в адресное пространство приложения.
    Для PCM_RING размер определяется вызовом GetBufferSize(SNDBUF hBuff, int *size);
    2. На сколько хватит ОЗУ.
    3. Да, хотя в этом нет необходимости.
    4. Статический буфер: простая звуковая сигнализация, озвучка интерфейса и т.п. Позволяет одновременно использовать звуковые данные в разных форматах.
    Потоковый буфер: различные аудиоплееры. Программа загружает большие объёмы звуковых данных из сети, накопителей или генерирует их в реальном времени.
    Кольцевой буфер: игры и другие приложения с повышенными требованиями к синхронности аудио- и видеоряда.
  • Т.е. для воспроизведения отдельных семплов-букв (в синтезаторе речи) мне хватит статического буфера? Или могут быть слишком большие промежутки?
  • Mario
    В твоём случае лучше потоковый или кольцевой. Для начала проще работать с потоковым.
  • Serge
    А что если я создам кучу буферов в памяти и буду подсовывать их при необходимости? Т.е. я так и не понял в чем принципиальное отличие статического и потокового буфера. В чем фишка? Объясни совсем уж по тупому "на пальцах".
  • Mario
    И получишь массу проблем с синхронизацией. Звук начинает выводиться не в момент вызова PlayBuffer, а спустя некоторое время после прерывания от контроллера. Для кольцевого буфера минимальная латентость 0.085с . Для остальных ещё хуже. В результате буферы попадающие в один квант звуковой карты (4096/48000 = 0.85(3) с) начнут воспроизводиться одновременно.
    Статический буфер это простая пищалка, один бип, дзинь и т.п.
    Потоковый буфер похож на чёрный ящик. Ты кидаешь в него байты, он превращает их в звук. Не важно сколько их, не важно что происходит внутри, рано или поздно он их все перемелет.
  • Не, ну так не хорошо вообще. Мне рано или поздно не нужно. Иначе будут заикания и прочий шлак. Получается только кольцевой нужно использовать.
  • Who is online

    Users browsing this forum: No registered users and 4 guests