Example #1
0
func (rsc *Mp3ReaderSeekerCloser) Format() (rate int64, channels int, encoding int, format Format) {
	c_rate := (*C.long)(unsafe.Pointer(&rate))
	c_channels := (*C.int)(unsafe.Pointer(&channels))
	c_encoding := (*C.int)(unsafe.Pointer(&encoding))
	C.mpg123_getformat(rsc.handle, c_rate, c_channels, c_encoding)
	if channels == 1 {
		if encoding&C.MPG123_ENC_8 != 0 {
			format = Mono8
		} else if encoding&C.MPG123_ENC_16 != 0 {
			format = Mono16
		}
	} else if channels == 2 {
		if encoding&C.MPG123_ENC_8 != 0 {
			format = Stereo8
		} else if encoding&C.MPG123_ENC_16 != 0 {
			format = Stereo16
		}
	}
	return
}
Example #2
0
func DecodeTrack(file string, control chan int) {

	var v1 *C.mpg123_id3v1
	var v2 *C.mpg123_id3v2

	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)
	}

	default_driver := C.ao_default_driver_id()
	var format C.ao_sample_format
	var device *C.ao_device

	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 {
		panic("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 {
			control <- 1
			break
		}
		C.ao_play(device, (*C.char)(unsafe.Pointer(&buf)), 16*1024)
	}
}
Example #3
0
// Returns current output format
func (d *Decoder) GetFormat() (rate int64, channels int, encoding int) {
	var cRate C.long
	var cChans, cEnc C.int
	C.mpg123_getformat(d.handle, &cRate, &cChans, &cEnc)
	return int64(cRate), int(cChans), int(cEnc)
}
Example #4
0
func (d *Decoder) Read(p []byte) (n int, err error) {
	d.mu.Lock()
	defer d.mu.Unlock()
	if d.closed {
		return 0, io.EOF
	}

	var stat C.int
loop:
	for {
		var rn int
		rn, err = d.src.Read(d.buf)
		if err != nil && err != io.EOF {
			return n, err
		}

		var cn C.size_t
		stat = C.mpg123_decode(d.mh,
			(*C.uchar)(unsafe.Pointer(&d.buf[0])), C.size_t(rn),
			(*C.uchar)(unsafe.Pointer(&p[n])), C.size_t(len(p)-n),
			&cn,
		)

		n += int(cn)

		switch stat {
		case C.MPG123_NEED_MORE:
			// mpg123 is asking for more data, so loop around if
			// we haven't reached EOF in the reader yet.
			if err == io.EOF {
				// We've exhausted the io.Reader and cleaned all
				// the internal buffers of mpg123, so we can signal
				// a proper EOF to our caller.
				return n, io.EOF
			}
			// Otherwise we just want more data
			break
		case C.MPG123_NEW_FORMAT:
			// mpg123 is notifying us of a new format coming up
			var rate C.long
			var chans, enc C.int
			err := toError(C.mpg123_getformat(d.mh, &rate, &chans, &enc))
			if err != nil {
				log.Println("error while getting stream format:", err)
			}
			fallthrough
		default:
			break loop
		}
	}

	// Check for read error from the src
	if err != nil && err != io.EOF {
		return n, err
	}

	if stat != C.MPG123_OK && stat != C.MPG123_NEW_FORMAT {
		return n, toError(stat)
	}

	return n, nil
}