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)
создает обратную петлю для считывания данных из входного потока и их воспроизведения в выходном.
Примеры
Настройка сквозной передачи звука с микрофона на динамик
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)