golang音频库发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。
Posted fly-iot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang音频库发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。相关的知识,希望对你有一定的参考价值。
目录
前言
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/108971807
未经博主允许不得转载。
博主CSDN地址是:https://blog.csdn.net/freewebsys
博主掘金地址是:https://juejin.cn/user/585379920479288
博主知乎地址是:https://www.zhihu.com/people/freewebsystem
1,关于beep和alsa库
ALSA(Advanced Linux Sound Architecture)是linux上主流的音频结构,在没有出现ALSA架构之前,一直使用的是OSS(Open Sound System)音频架构。
其他介绍:
https://blog.csdn.net/longwang155069/article/details/53260731
beep是一个golang的开源音频库:
Decode and play WAV, MP3, OGG, and FLAC.
Encode and save WAV.
Very simple API. Limiting the support to stereo (two channel) audio made it possible to simplify the architecture and the API.
Rich library of compositors and effects. Loop, pause/resume, change volume, mix, sequence, change playback speed, and more.
Easily create new effects. With the Streamer interface, creating new effects is very easy.
Generate completely own artificial sounds. Again, the Streamer interface enables easy sound generation.
Very small codebase. The core is just ~1K LOC.
https://github.com/faiface/beep
2,使用需要pkg-config和alsa库
# 安装工具pkg
sudo apt install pkg-config
# 安装 alsa 开发库
sudo apt-get install libalsa-ocaml-dev
最简单的一个代码:
package main
import (
"log"
"os"
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/speaker"
)
func main()
f, err := os.Open("./Lame_Drivers_-_01_-_Frozen_Egg.mp3")
if err != nil
log.Fatal(err)
streamer, format, err := mp3.Decode(f)
if err != nil
log.Fatal(err)
defer streamer.Close()
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func()
done <- true
)))
<-done
然后就可以听到声音播放了:
go run main.go
在linux 上可以使用:
$ arecord -l
**** CAPTURE 硬體裝置清單 ****
card 1: Generic_1 [HD-Audio Generic], device 0: ALC257 Analog [ALC257 Analog]
子设备: 1/1
子设备 #0: subdevice #0
其他,要是有多个音频设备呢?咋选择呢?
https://blog.csdn.net/lihuan680680/article/details/121941653
实际上beep 依赖另外一个库:oto
https://github.com/hajimehoshi/oto
// #cgo pkg-config: alsa
//
// #include <alsa/asoundlib.h>
import "C"
import (
"fmt"
"strings"
"sync"
"unsafe"
"github.com/hajimehoshi/oto/v2/internal/mux"
)
....
抄袭了下代码,可以通过main函数和alsa库,获得全部设备信息。
// Copyright 2021 The Oto Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !android && !darwin && !js && !windows && !nintendosdk
package main
// #cgo pkg-config: alsa
//
// #include <alsa/asoundlib.h>
import "C"
import (
"fmt"
"sync"
"unsafe"
)
type context struct
channelCount int
suspended bool
handle *C.snd_pcm_t
cond *sync.Cond
ready chan struct
var theContext *context
func alsaError(name string, err C.int) error
return fmt.Errorf("oto: ALSA error at %s: %s", name, C.GoString(C.snd_strerror(err)))
func deviceCandidates() []string
const getAllDevices = -1
cPCMInterfaceName := C.CString("pcm")
defer C.free(unsafe.Pointer(cPCMInterfaceName))
var hints *unsafe.Pointer
err := C.snd_device_name_hint(getAllDevices, cPCMInterfaceName, &hints)
if err != 0
return []string"default", "plug:default"
defer C.snd_device_name_free_hint(hints)
var devices []string
cIoHintName := C.CString("IOID")
defer C.free(unsafe.Pointer(cIoHintName))
cNameHintName := C.CString("NAME")
defer C.free(unsafe.Pointer(cNameHintName))
for it := hints; *it != nil; it = (*unsafe.Pointer)(unsafe.Pointer(uintptr(unsafe.Pointer(it)) + unsafe.Sizeof(uintptr(0))))
io := C.snd_device_name_get_hint(*it, cIoHintName)
defer func()
if io != nil
C.free(unsafe.Pointer(io))
()
if C.GoString(io) == "Input"
continue
name := C.snd_device_name_get_hint(*it, cNameHintName)
defer func()
if name != nil
C.free(unsafe.Pointer(name))
()
if name == nil
continue
goName := C.GoString(name)
if goName == "null"
continue
if goName == "default"
continue
devices = append(devices, goName)
devices = append([]string"default", "plug:default", devices...)
return devices
func main()
deviceList := deviceCandidates()
for idx,device := range deviceList
println(idx)
println(device)
3,总结
可以使用golang 然后控制音频,播放音乐,也是非常不错的库,库也是非常的强大。
可以需要在linux上,调用alsa的库,然后播放音频mp3文件。
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/108971807
用 Go 编写的音频库?
【中文标题】用 Go 编写的音频库?【英文标题】:Audio Libraries Written in Go? 【发布时间】:2013-11-15 17:21:38 【问题描述】:是否有任何本地 Go 音频库?具体来说,我想从音频文件中读取峰值以构建波形。或者,我知道我可以使用 SWIG 之类的东西来绑定已建立的 C++ 音频库。但是,如果有可用的 Go 库,我想使用它。它会更干净,而且我不需要在学习如何使用库的同时学习如何使用 SWIG。
【问题讨论】:
如果你只是使用 C 库,你可以使用 cgo (golang.org/cmd/cgo),无需与 SWIG 混淆…… @filmor - 谢谢!你知道任何好的纯 C 音频库吗?我一直在考虑走这条路,但我听说很多音频库最终都包含大量 C++,这就是我选择 SWIG 的原因。 【参考方案1】:以下是用 go 编写的“音乐”库列表:
https://github.com/golang/go/wiki/Projects#music
这里是用 go 编写的“图形和音频”库的列表:
https://github.com/golang/go/wiki/Projects#graphics-and-audio
该页面不区分纯 go 和链接到 c 库的代码。我猜大多数项目都会链接到之前评论中提到的现有库。
【讨论】:
以上是关于golang音频库发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。的主要内容,如果未能解决你的问题,请参考以下文章