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

PortAudio.jl

PortAudio.jl — это оболочка для libportaudio, которая обеспечивает кроссплатформенный доступ к аудиоустройствам. Она совместима с типами, определенными в SampledSignals.jl. Она предоставляет тип PortAudioStream, из которого можно считывать данные и в который их можно записывать.

Открытие потока

Самый простой способ открыть источник или приемник — использовать конструктор по умолчанию PortAudioStream(), который открывает поток с 2 каналами ввода и 2 каналами вывода для устройств по умолчанию в системе. Конструктор также может принимать количество каналов ввода и вывода в качестве позиционных аргументов, а также имеет ряд именованных аргументов. Если не задан именованный аргумент latency или samplerate, PortAudio использует значения по умолчанию для устройства.

PortAudioStream(inchans=2, outchans=2; eltype=Float32, samplerate=48000, latency=0.1)

Чтобы открыть определенное устройство, укажите его в первом аргументе как экземпляр PortAudioDevice либо по имени. Если нужны разные устройства ввода и вывода, их можно указывать по отдельности.

PortAudioStream(device::PortAudioDevice, args...; kwargs...)
PortAudioStream(devname::AbstractString, args...; kwargs...)

Получить список устройств в системе можно с помощью функции PortAudio.devices():

julia> PortAudio.devices()
14-element Vector{PortAudio.PortAudioDevice}:
 "sof-hda-dsp: - (hw:0,0)" 2→2
 "sof-hda-dsp: - (hw:0,3)" 0→2
 "sof-hda-dsp: - (hw:0,4)" 0→2
 "sof-hda-dsp: - (hw:0,5)" 0→2
 ⋮
 "upmix" 8→8
 "vdownmix" 6→6
 "dmix" 0→2
 "default" 32→32

Чтение и запись

У типа PortAudioStream есть поля source и sink, которые имеют тип PortAudioSource <: SampleSource и PortAudioSink <: SampleSink соответственно. Эти типы являются подтипами SampleSource и SampleSink (из SampledSignals.jl). Это означает, что они поддерживают все определенные в этом пакете функции потоков и буферов. Например, при загрузке SampledSignals с помощью using SampledSignals можно считать данные за 5 секунд в буфер с помощью buf = read(stream.source, 5s) независимо от частоты дискретизации устройства.

PortAudio.jl также предоставляет удобные оболочки вокруг типа PortAudioStream, позволяющие выполнять чтение и запись напрямую. Например, write(stream, stream) создает обратную петлю для считывания данных из входного потока и их воспроизведения в выходном.

Отладка

Если у вас возникли проблемы и вы хотите просмотреть подробную отладочную информацию и данные журнала, задайте

ENV["JULIA_DEBUG"] = :PortAudio

перед использованием пакета.

Примеры

Настройка сквозной передачи звука с микрофона на динамик

stream = PortAudioStream(2, 2)
try
    # для отмены нажмите CTRL+C
    write(stream, stream)
finally
    close(stream)
end

Для автоматического закрытия потока используйте синтаксис do

PortAudioStream(2, 2) do stream
    write(stream, stream)
end

Открытие встроенных микрофона и динамика по имени

PortAudioStream("default", "default") do stream
    write(stream, stream)
end

Запись звука в течение 10 секунд и сохранение записи в OGG-файл

julia> import LibSndFile # для работы FileIO.save должно быть в манифесте

julia> using PortAudio: PortAudioStream

julia> using SampledSignals: s

julia> using FileIO: save

julia> stream = PortAudioStream(1, 0) # устройство ввода по умолчанию (например, встроенный микрофон)
PortAudioStream{Float32}
  Samplerate: 44100.0Hz
  2 channel source: "default"

julia> buf = read(stream, 10s)
480000-frame, 2-channel SampleBuf{Float32, 2, SIUnits.SIQuantity{Int64,0,0,-1,0,0,0,0,0,0}}
10.0 s at 48000 s⁻¹
▁▄▂▃▅▃▂▄▃▂▂▁▁▂▂▁▁▄▃▁▁▄▂▁▁▁▄▃▁▁▃▃▁▁▁▁▁▁▁▁▄▄▄▄▄▂▂▂▁▃▃▁▃▄▂▁▁▁▁▃▃▂▁▁▁▁▁▁▃▃▂▂▁▃▃▃▁▁▁▁
▁▄▂▃▅▃▂▄▃▂▂▁▁▂▂▁▁▄▃▁▁▄▂▁▁▁▄▃▁▁▃▃▁▁▁▁▁▁▁▁▄▄▄▄▄▂▂▂▁▃▃▁▃▄▂▁▁▁▁▃▃▂▁▁▁▁▁▁▃▃▂▂▁▃▃▃▁▁▁▁

julia> close(stream)

julia> save(joinpath(homedir(), "Desktop", "myvoice.ogg"), buf)

Воспроизведение звукового сигнала через устройство вывода звука по умолчанию

using PortAudio, SampledSignals
S = 8192 # частота дискретизации (сэмплов в секунду)
x = cos.(2pi*(1:2S)*440/S) # Тон A440 в течение 2 секунд
PortAudioStream(0, 2; samplerate=S) do stream
    write(stream, x)
end