Skip to content

Instantly share code, notes, and snippets.

@deepakjois
Created June 29, 2011 04:16
Show Gist options
  • Save deepakjois/1053100 to your computer and use it in GitHub Desktop.
Save deepakjois/1053100 to your computer and use it in GitHub Desktop.
Playing audio using libmpg123 and libao
$ ./main ~/Music/mpd/demo.mp3
ID3V2 tag found
Dil Main Chuppa Ke Pyar Ka
Angelique Kidjo
Oyo
World
SIGTRAP: trace trap
pc: 0x7fff844715c0
goroutine 2 [3]:
return /Users/deepak/code/public/go/src/pkg/runtime/amd64/asm.s:384
return()
runtime.cgocall+0x108 /Users/deepak/code/public/go/src/pkg/runtime/cgocall.c:136
runtime.cgocall(0x15825, 0x21b8e60, 0x0, 0x15010)
mp3._Cfunc_ao_initialize+0x2f /Users/deepak/code/personal/gomp3/_obj/_cgo_defun.c:163
mp3._Cfunc_ao_initialize(0xf840022510, 0x100000001)
mp3.DecodeTrack+0x589 /Users/deepak/code/personal/gomp3/_obj/music.cgo1.go:-133
mp3.DecodeTrack(0x7fff5fbff7d7, 0x49)
main._func_001+0x3e /Users/deepak/code/personal/gomp3/main.go:9
main._func_001()
runtime.goexit /Users/deepak/code/public/go/src/pkg/runtime/proc.c:178
runtime.goexit()
----- goroutine created by -----
main.main+0x2b /Users/deepak/code/personal/gomp3/main.go:10
goroutine 1 [3]:
runtime.entersyscall+0x78 /Users/deepak/code/public/go/src/pkg/runtime/proc.c:639
runtime.entersyscall()
syscall.Syscall6+0x5 /Users/deepak/code/public/go/src/pkg/syscall/asm_darwin_amd64.s:38
syscall.Syscall6()
syscall.Select+0x63 /Users/deepak/code/public/go/src/pkg/syscall/zsyscall_darwin_amd64.g
o:754
syscall.Select(0x100000000, 0x0, 0x0, 0x0, 0xf8400223f0, ...)
syscall.Sleep+0x7a /Users/deepak/code/public/go/src/pkg/syscall/syscall_bsd.go:150
syscall.Sleep(0x12a05f200, 0x8, 0xf8400223b0, 0x18e8c)
time.sysSleep+0x25 /Users/deepak/code/public/go/src/pkg/time/sys_posix.go:13
time.sysSleep(0x12a05f200, 0x0, 0x4e0aa618, 0x122ba4451b0996c8)
time.sleep+0x40 /Users/deepak/code/public/go/src/pkg/time/sys.go:44
time.sleep(0x122ba443f103a4c8, 0x12a05f200, 0x21b7f90, 0x202b, 0x8, ...)
time.Sleep+0x33 /Users/deepak/code/public/go/src/pkg/time/sys.go:33
time.Sleep(0x12a05f200, 0x0, 0xde02, 0x2e64)
main.main+0x40 /Users/deepak/code/personal/gomp3/main.go:12
main.main()
runtime.mainstart+0xf /Users/deepak/code/public/go/src/pkg/runtime/amd64/asm.s:77
runtime.mainstart()
runtime.goexit /Users/deepak/code/public/go/src/pkg/runtime/proc.c:178
runtime.goexit()
----- goroutine created by -----
_rt0_amd64+0x8e /Users/deepak/code/public/go/src/pkg/runtime/amd64/asm.s:64
rax 0x0
rbx 0x7fff8446fb58
rcx 0x7fff5fbff7b8
rdx 0x7fff5fbff6d8
rdi 0x0
rsi 0x7fff5fbff6c0
rbp 0xb00809b0
rsp 0xb0080160
r8 0x7fff5fc40548
r9 0x2201060
r10 0x1
r11 0x3
r12 0x7fff84470eb0
r13 0x7fff5fc404a0
r14 0x5
r15 0x2200bf0
rip 0x7fff844715c0
rflags 0x246
cs 0x27
fs 0x0
gs 0x0
package main
import "mp3"
import "os"
import "time"
func main() {
go func() {
mp3.DecodeTrack(os.Args[1])
}()
time.Sleep(5e9)
}
package mp3
// #cgo LDFLAGS: -lmpg123 -lao -ldl -lm
/*
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include "mpg123.h"
#include <ao/ao.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
func DecodeTrack(file string) {
var v1 *C.mpg123_id3v1
var v2 *C.mpg123_id3v2
C.mpg123_init()
defer C.mpg123_exit()
m := C.mpg123_new(nil, nil)
defer C.mpg123_delete(m)
f := C.CString(file)
if err := C.mpg123_open(m, f); err != C.MPG123_OK {
panic("Error reading file")
}
defer C.mpg123_close(m)
C.mpg123_scan(m)
meta := C.mpg123_meta_check(m)
if meta == C.MPG123_ID3 && C.mpg123_id3(m, &v1, &v2) == C.MPG123_OK {
var title, artist, album, genre string
switch false {
case v2 == nil:
fmt.Println("ID3V2 tag found")
title = C.GoString(v2.title.p)
artist = C.GoString(v2.artist.p)
album = C.GoString(v2.album.p)
genre = C.GoString(v2.genre.p)
case v1 == nil:
fmt.Println("ID3V2 tag found")
title = C.GoString(&v1.title[0])
artist = C.GoString(&v1.artist[0])
album = C.GoString(&v1.album[0])
genre = "Unknown" // FIXME convert int to string
}
fmt.Println(title)
fmt.Println(artist)
fmt.Println(album)
fmt.Println(genre)
}
C.ao_initialize()
defer C.ao_shutdown()
default_driver := C.ao_default_driver_id()
var format C.ao_sample_format
var device *C.ao_device
//C.memset(&format,0,unsafe.Sizeof(format))
var channels, encoding C.int
var rate C.long
C.mpg123_getformat(m, &rate, &channels, &encoding)
format.bits = 16
format.channels = channels
format.rate = C.int(rate)
format.byte_format = C.AO_FMT_LITTLE
device = C.ao_open_live(default_driver, &format, nil)
if device == nil {
fmt.Println("Error opening device")
return
}
defer C.ao_close(device)
var ret C.int
var fill C.size_t
buf := make([]C.uchar,1024*16)
for {
ret = C.mpg123_read(m, (*C.uchar)(unsafe.Pointer(&buf)), 16*1024, &fill)
if ret == C.MPG123_DONE {
break
}
C.ao_play(device,(*C.char)(unsafe.Pointer(&buf)),16*1024)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment