Войти
ПрограммированиеФорумЗвук

OpenAL вывод звука с микрофона

#0
20:51, 31 мар. 2011

Здравствуйте.
Пытаюсь одновременно записывать звук и выводить и что-то не очень получается гугл выдал пример Во
но он тоже не работает.
Вот мой код:

#include <iostream>
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alut.h"

int main() {
    ALCdevice * in_device;
    ALCdevice * out_device;
    ALCcontext * context = NULL;
    int   read_buf_size = 44100;
    int  play_buf_size = 1024;

    char * captureDevices = (char *) alcGetString ( NULL, ALC_CAPTURE_DEVICE_SPECIFIER );
    if ( captureDevices == NULL )
        std::cout<<"No capture devices found\n";
    else
        std::cout<<"Capture devices:  "<< captureDevices<<std::endl ;

    alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
    in_device =  alcCaptureOpenDevice(NULL, 44100, AL_FORMAT_MONO16, read_buf_size);

    out_device = alcOpenDevice (0);
    context = alcCreateContext(out_device, 0);
    alcMakeContextCurrent(context);
    alcCaptureStart(in_device);
    ALint *dest;
    ALCvoid * buf;
    ALCsizei samples = 44100;
    ALsizei size = 0;

    ALuint buffer;
    ALuint source;

    alGenBuffers ( 1, &buffer );
    alGenSources(1,&source);
    alSourceQueueBuffers(source, 1, &buffer);
    alSourcePlay(source);
    while(true) {

        alcGetIntegerv(in_device,ALC_ATTRIBUTES_SIZE,44100,dest);
        alcCaptureSamples ( in_device, buf,  samples );
        alBufferData (buffer, AL_FORMAT_MONO16, dest, size, 16 );

    }
    alcCaptureStop(in_device);
    alcCaptureCloseDevice(in_device);

    alcDestroyContext ( context );
    alcCloseDevice    ( out_device  );

}
Помогите разобраться!
(Linux)


#1
11:34, 2 апр. 2011

Если кому то надо рабочий код записи с микрофона и воспроизведение то вот:

#include <iostream>
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alut.h"

const int BUF_COUNT = 5;

class SoundManager {
    ALCdevice * in_device;
    ALCdevice * out_device;
    ALCcontext * context;
    ALuint al_source;
    ALuint al_buffers[BUF_COUNT];
    ALshort *play_buf[44100];
    int read_buf_size;
    int play_buf_size;
    ALenum  error ;
public:
    SoundManager() {
        error = 0;
        read_buf_size = 44000;
        play_buf_size = 44000;
        play_buf = {0};

        // Инициализируем OpenAL и создаем всякие штучки
        out_device = alcOpenDevice (0);
        context = alcCreateContext(out_device, 0);
        alcMakeContextCurrent(context);

        const char * szDefaultCaptureDevice = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);

        in_device = alcCaptureOpenDevice (szDefaultCaptureDevice, 44100, AL_FORMAT_STEREO16, read_buf_size);
        if( (error=  alcGetError(in_device)) != AL_NO_ERROR)
            std::cout<<error<<" alcCaptureOpenDevice "<<__LINE__<<"\n";
        alGenSources(1, &al_source);
        alGenBuffers(BUF_COUNT, al_buffers);

        // Заполняем первую очередь
        for (int i = 0; i < BUF_COUNT; ++i) {
            alBufferData(al_buffers[i], AL_FORMAT_MONO16, play_buf, play_buf_size * sizeof(ALshort), play_buf_size);
        }
        // Здесь начинаем запись и воспроизведение
        alSourceQueueBuffers(al_source, BUF_COUNT, al_buffers);
        alSourcePlay(al_source);
        alcCaptureStart(in_device);
        if( (error=  alcGetError(in_device)) != AL_NO_ERROR)
            std::cout<<error<<" alcCaptureStart "<<__LINE__<<"\n";
    }
    void update() {
        ALint samples, val, state;
        // Если источник вдруг перестал играть, то пнем его
        alGetSourcei (al_source, AL_SOURCE_STATE,  &state);
        if (state != AL_PLAYING) alSourcePlay(al_source);

        alcGetIntegerv(in_device, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
        if( (error=  alcGetError(in_device)) != AL_NO_ERROR)
            std::cout<<error<<" alcGetIntegerv "<<__LINE__<<"\n";
        alGetSourcei (al_source, AL_BUFFERS_PROCESSED , &val);
        // Пока есть свободные буферы воспроизведения и пока есть готовые
        // данные, которые надо воспроизвести, считываем из захвата и
        // пишем на выход

        while ( ( (val--) > 0) && (samples < play_buf_size)   ) {
            ALuint buffer;
            alcCaptureSamples(in_device, play_buf, samples);

            alSourceUnqueueBuffers(al_source, 1, &buffer);
            alBufferData(buffer, AL_FORMAT_STEREO16, play_buf, play_buf_size * sizeof(ALshort), play_buf_size);
            alSourceQueueBuffers(al_source, 1, &buffer);
            alcGetIntegerv(in_device, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
        }
    }
    void process() { }
    ~SoundManager() {
        alcCaptureStop(in_device);
        alcCaptureCloseDevice(in_device);
    }
};
int main() {
    SoundManager s;
    while (1) {
        s.update();
    }
}

Не помню где-то я его нашел  и исправил ошибки)
При работе этого кода есть задержка при воспроизведения может знает как её убрать?

#2
11:53, 2 апр. 2011

Код не смотрел.

Задержка при воспроизведении - неотъемлемое свойство звука на IBM PC, избавиться от нее, не меняя железа, невозможно. Можно лишь уменьшить, уменьшая размер звукового буфера.

ПрограммированиеФорумЗвук

Тема в архиве.