Git Product home page Git Product logo

go-mp3's Introduction

go-mp3's People

Contributors

alexdor avatar alistanis avatar dudk avatar gonutz avatar hajimehoshi avatar qbit avatar steinhae avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-mp3's Issues

panic in internal/maindata.readHuffman

Hi,
i write simple program to read all mp3 files, just to check that they are not corrupted, but get panic after some errors
(note readHuffman failed)
i work in gopath mode (use latest source)

2022/11/01 09:14:06 mp3: free bitrate format is not supported. Header word is 0xffe607df at position 344519
2022/11/01 09:14:11 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:14:16 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:14:17 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:14:26 mp3: free bitrate format is not supported. Header word is 0xffff0000 at position 3310324
2022/11/01 09:14:30 mp3: free bitrate format is not supported. Header word is 0xffff0400 at position 3680769
2022/11/01 09:14:39 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:14:43 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:14:59 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:15:13 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:15:29 mp3: readHuffman failed: invalid index j: 24
2022/11/01 09:15:43 mp3: only layer3 (want 1; got 3) is supported
2022/11/01 09:15:53 mp3: free bitrate format is not supported. Header word is 0xffff00b5 at position 3409454
2022/11/01 09:15:54
panic: runtime error: index out of range [-4]

goroutine 6 [running]:
github.com/hajimehoshi/go-mp3/internal/maindata.readHuffman(0xc0000142d0, 0x2?, 0xc0001322c0, 0xc0000f3000, 0xc0001cc000?, 0xc000132f38?, 0x1)
	/home/jambo/golang/src/github.com/hajimehoshi/go-mp3/internal/maindata/huffman.go:124 +0x5cf
github.com/hajimehoshi/go-mp3/internal/maindata.getScaleFactorsMpeg2(0xc0000142d0, 0xfff38250, 0xc0001322c0)
	/home/jambo/golang/src/github.com/hajimehoshi/go-mp3/internal/maindata/maindata.go:172 +0x1e6
github.com/hajimehoshi/go-mp3/internal/maindata.Read({0x7fb59b2e60f8, 0xc0001cc000}, 0xfff38250?, 0xfff38250, 0xc0001322c0)
	/home/jambo/golang/src/github.com/hajimehoshi/go-mp3/internal/maindata/maindata.go:111 +0x117
github.com/hajimehoshi/go-mp3/internal/frame.Read({0x4e9588?, 0xc0001cc000}, 0x0?, 0xc000446000)
	/home/jambo/golang/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:97 +0x155
github.com/hajimehoshi/go-mp3.(*Decoder).readFrame(0xc0004a5200)
	/home/jambo/golang/src/github.com/hajimehoshi/go-mp3/decode.go:42 +0x34
github.com/hajimehoshi/go-mp3.(*Decoder).Read(0xc0004a5200, {0xc0004c8e98, 0x1000, 0x1000?})
	/home/jambo/golang/src/github.com/hajimehoshi/go-mp3/decode.go:60 +0x4a
main.decode({0xc0000208c0?, 0x39?})
	/home/jambo/go/src/jambo/cmd/mediacheck/check.go:30 +0x205
main.Decode({0xc0000208c0, 0x39})
	/home/jambo/go/src/jambo/cmd/mediacheck/check.go:43 +0x5f
main.do(0x0?, 0x0?)
	/home/jambo/go/src/jambo/cmd/mediacheck/check.go:52 +0x71
created by main.main
	/home/jambo/go/src/jambo/cmd/mediacheck/check.go:118 +0xb7

package main

import (
	"flag"
	"fmt"
	"io"
	"io/fs"
	"log"
	"os"
	"path/filepath"
	"sync"

	"github.com/hajimehoshi/go-mp3"
)

func decode(p string) error {
	f, err := os.Open(p)
	if err != nil {
		log.Println(err)
		return err
	}
	defer f.Close()
	d, err := mp3.NewDecoder(f)
	if err != nil {
		log.Println(err)
		return err
	}
	for {
		var buf [4096]byte
		_, err := d.Read(buf[:])
		if err != nil {
			if err != io.EOF {
				log.Println(err)
				return err
			}
			return nil
		}
	}
}

func Decode(p string) {
	log.Println(p)
	err := decode(p)
	if err != nil {
		log.Println(p, err)
	}
}

func do(f chan string, wg *sync.WaitGroup) {
	defer wg.Done()
	for p := range f {
		Decode(p)
	}
}

var walkfiles chan string

func visitDir(path string, d fs.DirEntry, err error) error {

	if err != nil {
		log.Println(path, err)
		return err
	}

	if d.Type().IsRegular() {
		ext := filepath.Ext(path)
		if ext != ".mp3" {
			fmt.Println(path)
			// if ext == ".MP3" {
			// 	os.Rename(path, path[:len(path)-3]+"mp3")
			// 	fmt.Println(path[:len(path)-3] + "mp3")
			// }

		} else {
			// fmt.Println(path)
			// decode(path)
			walkfiles <- path
		}
	}
	return nil
}

func main() {
	const N = 12
	var wg sync.WaitGroup

	flag.Parse()
	walkfiles = make(chan string, N*2)
	for i := 0; i < N; i++ {
		wg.Add(1)
		go do(walkfiles, &wg)
	}

	for _, root := range flag.Args() {

		// err := filepath.Walk(root, visit)
		err := filepath.WalkDir(root, visitDir)
		if err != nil {
			log.Println(root, err)
		}
	}
	close(walkfiles)
	wg.Wait()
}

Change speed while reproducing

Hello, thanks for this great library. I was wondering if there's a way to change the speed while reproducing an mp3 file. I don't have experience working with mp3 at this level so this is more a beginner question.

Thanks in advance.

panic: runtime error: invalid memory address or nil pointer dereference

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49408a]

goroutine 1 [running]:
github.com/hajimehoshi/go-mp3.(*source).readNextFrame(0xc4200780c0, 0x0, 0xc42008e018, 0x7fa7adbcd028, 0xc42008e018, 0x1)
        /home/faiface/go/src/github.com/hajimehoshi/go-mp3/read.go:42 +0x6a
github.com/hajimehoshi/go-mp3.NewDecoder(0x728be0, 0xc42008e018, 0xc42008e018, 0x0, 0x0)
        /home/faiface/go/src/github.com/hajimehoshi/go-mp3/decode.go:291 +0x119

This happens when I attempt to play any song converted to MP3 using VLC and a few other files.

MPEG2 support

It seems ebiten cannot play certain mp3 files in mpeg format other than 1.

mp3: only MPEG version 1 (want 3; got 2) is supported

This means, we cannot always expect MP3 we download from the internet to work all the time, this is pretty inconvenient. Currently I am looking for a way to convert MPEG version on my own, but it would be nice if go-mp3 can support multiple versions.

Large repo

Awesome work!

All go gets for github.com/hajimehoshi/go-mp3 will include the 10MB example mp3, useful for testing though maybe a shell script to wget the example file might be better? However, this would require git history change which isn't optimal either...

panic: runtime error: index out of range in stereoProcessIntensityShort

Hello.

I found a index out of range bug in go-mp3.

Please confirm.

Thanks.

reproduce code:

package mp3

import (
	"bytes"
	"testing"
)

type bytesReadCloser struct {
	*bytes.Reader
}

func (b *bytesReadCloser) Close() error {
	return nil
}

func TestFuzzing(t *testing.T) {
	inputs := []string{
		"\xff\xfb%S000000v000\x00\x010000" +
		"00000000000000000000" +
		"0000\xf4000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000",
		
	}
	for _, input := range inputs {
		b := &bytesReadCloser{bytes.NewReader([]byte(input))}
		_, _ = NewDecoder(b)
	}
}

Log

--- FAIL: TestFuzzing (0.00s)
panic: runtime error: index out of range [recovered]
	panic: runtime error: index out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc42004c750)
	/usr/lib/go-1.8/src/testing/testing.go:622 +0x29d
panic(0x527020, 0x5e99f0)
	/usr/lib/go-1.8/src/runtime/panic.go:489 +0x2cf
github.com/hajimehoshi/go-mp3/internal/frame.(*Frame).stereoProcessIntensityShort(0xc4200b6000, 0x0, 0x5)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:337 +0x293
github.com/hajimehoshi/go-mp3/internal/frame.(*Frame).stereo(0xc4200b6000, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:398 +0x3b3
github.com/hajimehoshi/go-mp3/internal/frame.(*Frame).Decode(0xc4200b6000, 0xc4200149c0, 0x0, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:126 +0x119
github.com/hajimehoshi/go-mp3.(*Decoder).readFrame(0xc420018a20, 0x0, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/decode.go:52 +0x17f
github.com/hajimehoshi/go-mp3.NewDecoder(0x5d8ca0, 0xc42000c098, 0x78, 0xc42005a980, 0x78)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/decode.go:207 +0xc0
github.com/hajimehoshi/go-mp3.TestFuzzing(0xc42004c750)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/fuzzing_test.go:29 +0x126
testing.tRunner(0xc42004c750, 0x554a40)
	/usr/lib/go-1.8/src/testing/testing.go:657 +0x96
created by testing.(*T).Run
	/usr/lib/go-1.8/src/testing/testing.go:697 +0x2ca
exit status 2
FAIL	github.com/hajimehoshi/go-mp3	0.006s

Function hangs on second call

I have the following part of my function:

// Play mp3 file
	f, err := os.Open(fmt.Sprintf("./cachedAudio/%s-%s.mp3", spokenName, status))
	if err != nil {
		panic(err)
	}

	d, err := mp3.NewDecoder(f)
	if err != nil {
		panic(err)
	}

	c, err := oto.NewContext(d.SampleRate(), 2, 2, 8192)
	if err != nil {
		panic(err)
	}

	p := c.NewPlayer() // HERE
	if _, err := io.Copy(p, d); err != nil {
		return false, err
	}
	fmt.Println(2)

	p.Close()
	c.Close()
	f.Close()

When I call the function for the first time, it works fine. However any subsequent calls hang at the time marked // HERE. It seems as if the NewPlayer() function just blocks forever. When I run with goroutines, I end up getting the following error after a few calls:

panic: oto: NewContext can be called only once

Analysing samples?

Hi,

What approach do you recommend if I want to analyse (not play) the decoded audio samples from the mp3 file? It appears that the Decoder only gives out bytes, and since samples are 2x16-bit values, what is the recommended way of getting a stream of such 2x16-bit samples?

fatal error: unexpected signal during runtime execution

Attempting to play files always results in a stack dump at the end.

Here's my play function:

func (e *Episode) Play() error {
	// Get MP3 url
	req, err := http.Get(e.Mp3)
	if err != nil {
		return err
	}
	defer req.Body.Close()

	dec, err := mp3.NewDecoder(req.Body)
	if err != nil {
		return err
	}

	ctx, err := oto.NewContext(dec.SampleRate(), 2, 2, 4096)
	if err != nil {
		return err
	}
	defer ctx.Close()

	plr := ctx.NewPlayer()
	defer plr.Close()

	fmt.Printf("Episode: %s\n", e.Title)
	if _, err := io.Copy(plr, dec); err != nil {
		return err
	}

	// Dont forget to write the store after each succesful play
	e.Played = true
	return nil
}

Stack dump attached
dump.txt

The file plays correctly and panics immediately after.

Consumes too much memory with longer MP3 files

I was just playing 'Stardust - Music Sounds Better With You' (6m44s long song) using the example and it consumes 638MB of RAM. I think this is caused by reading decoding the whole file into the memory, instead of reading decoding it lazily on demand.

panic: runtime error: index out of range at read.go:177

Steps to reproduce:

  1. Using File: aws.mp3.zip
  2. call Decode() on the file

Expected result:

The file is decoded successfully.

Actual result:

panic: runtime error: index out of range

Notes

  • ( sideInfo.big_values[gr][ch] * 2 ) > len(mainData.is[gr][ch]), so is_pos causes index out of range
  • file does not cause issues with other players
  • all aws polly mp3 streams cause same issue

Stack Trace:

panic: runtime error: index out of range

goroutine 1 [running]:
github.com/hajimehoshi/go-mp3.readHuffman(0xc4200163f0, 0xc420010308, 0xc420094000, 0xc420098000, 0xa01, 0x1, 0x0, 0x0, 0x0)
/home/.../go/src/github.com/hajimehoshi/go-mp3/read.go:177 +0x245
github.com/hajimehoshi/go-mp3.(*source).readMainL3(0xc420016360, 0x0, 0xc420010308, 0xc420094000, 0x0, 0x0, 0x0, 0x10)
/home/.../go/src/github.com/hajimehoshi/go-mp3/maindata.go:137 +0x4a4
github.com/hajimehoshi/go-mp3.(*source).readNextFrame(0xc420016360, 0x0, 0xc42000e028, 0x7f7f89d8b028, 0xc42000e028, 0x1)
/home/.../go/src/github.com/hajimehoshi/go-mp3/read.go:62 +0xfe
github.com/hajimehoshi/go-mp3.NewDecoder(0x728c00, 0xc42000e028, 0xc42000e028, 0x0, 0x0)
/home/.../go/src/github.com/hajimehoshi/go-mp3/decode.go:291 +0x119
main.run(0x0, 0x0)
/home/.../go/src/github.com/hajimehoshi/go-mp3/example/main.go:34 +0xa8
main.main()
/home/.../go/src/github.com/hajimehoshi/go-mp3/example/main.go:53 +0x22
exit status 2

Usage to cut mp3 segment

i am using go-mp3 to cut mp3 file, but encountered the problem shown as follows:
i defined the size of 441000 bytes, but got only 1368 bytes. Why?

mp3

The following is my code:

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"

	"github.com/hajimehoshi/go-mp3"
)

func main() {
	buf, err := readMP3("34YBAFdskzmAUMlOADSMOxgm3l4714.mp3")
	if err != nil {
		fmt.Println(err)
	}

	err = ioutil.WriteFile("output.mp3", buf, os.ModePerm)
	if err != nil {
		fmt.Println(err)
	}
}

func readMP3(file string) ([]byte, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	d, err := mp3.NewDecoder(f)
	if err != nil {
		return nil, err
	}
	fmt.Println("mp3 length: ", d.Length())

	st := 10
	et := 20

	startPos := byteOfSecond(st, d.SampleRate())
	endPos := byteOfSecond(et, d.SampleRate())
	size := endPos - startPos
	// seek to the start position
	pos, err := d.Seek(int64(startPos), io.SeekStart)
	if err != nil {
		return nil, err
	}
	fmt.Println("current pos", pos)

	buf := make([]byte, size)
	n, err := d.Read(buf)
	if err != nil {
		return nil, err
	}
	fmt.Printf("readed %d bytes from mp3 file\n", n)

	return buf, nil
}

func byteOfSecond(sec int, freq int) int {
	return sec * freq
}

Audio distortion on playback of lower bitrate files

I'm working on a toy resource-viewer for a well known game and I have a set of mp3s (BGM) that I'm trying to play using go-mp3 + oto which all have audible distortion. ffplay is able to play them all just fine.

I'm running on MacOS Catalina (10.15.6).

ffmpeg -i 01.mp3
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with Apple clang version 11.0.3 (clang-1103.0.32.62)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, mp3, from '01.mp3':
  Metadata:
    encoder         : Lavf58.45.100
  Duration: 00:01:14.66, start: 0.023991, bitrate: 80 kb/s
    Stream #0:0: Audio: mp3, 22050 Hz, stereo, fltp, 80 kb/s

It plays fine when I re-encoded it with libmp3lame at a higher bitrate via: fmpeg -i 01.mp3 -codec:a libmp3lame -qscale:a 2 output.mp3, and re-encoding (with libmp3lame again) it again at a low bitrate causes the issues to reappear.

Relevant playback code on my side:

        ...
        d, err := mp3.NewDecoder(bytes.NewBuffer(b))
	if err != nil {
		return err
	}

	c, err := oto.NewContext(d.SampleRate(), 2, 2, 4096)
	if err != nil {
		return err
	}
        ...

Any tips on what the issue might be given that these play fine on other mp3 players? Tuning the sample rate and buffer size in bytes parameters have not helped.

I've uploaded the file here if you'd like to take a look.

Intermittent "Slice bounds out of range" during decoding

I have noticed an intermittent panic error that occurs during decoding. This happens specifically when seek is called several times in quick succession. (e.g rapidly clicking).
It might be appropriate to debounce seeking, however I thought I'd raise this anyway as I'm not sure.

panic: runtime error: slice bounds out of range [5696:4608]

The panic occurs here:

d.buf = d.buf[d.bytesPerFrame+(d.pos%d.bytesPerFrame):]

I can reproduce this using the following faiface/beep code. It seems possible that this is a bug within beep. I don't understand the situation well enough so I have decided to at least put this on your radar.

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/faiface/beep"
	"github.com/faiface/beep/mp3"
	"github.com/faiface/beep/speaker"
)

var soundFormat *beep.Format
var musicStreamer *beep.StreamSeekCloser

func prepareStreamer(file string) (*beep.StreamSeekCloser, *beep.Format) {
	sound, _ := os.Open(file)
	streamer, format, err := mp3.Decode(sound)
	if err != nil {
		panic(err)
	}
	return &streamer, &format
}

func main() {
	musicStreamer, soundFormat = prepareStreamer("an.mp3")
	speaker.Init(soundFormat.SampleRate, soundFormat.SampleRate.N(time.Second/10))

	speaker.Clear()
	s := *musicStreamer
	s.Seek(0)
	speaker.Play(s)

	ch := make(chan int)
	go func() {
		for true {
			time.Sleep(250 * time.Millisecond)
			fmt.Println("seeking")
			streamer := *musicStreamer
			streamer.Seek(700000) // anywhere into the song
		}
	}()
	<-ch

	defer s.Close()
}

One way to fix this:

bufLength := int64(len(d.buf))
idx := d.bytesPerFrame + (d.pos % d.bytesPerFrame)
if idx > bufLength {
	idx = bufLength
}

However I don't understand the underlying cause so there may be a better solution.

macOS is supported?

Hi @hajimehoshi , I am trying to use your mp3 library here https://github.com/gen2brain/malgo/blob/master/examples/playback/playback.go , it works on Linux but on macOS ( I am trying in vmware, don't have real hardware :( ) it sounds like 2x or 3x slower. Do you think something can work differently on macOS?

It can be anything really, I am working on https://github.com/dr-soft/mini_al bindings for Go, but I can play wav on macOS with same example, and mp3 works on Linux, but on macOS there is an issue. I thought at first that there is an issue with OpenAL backend, but if I force OpenAL on Linux instead of alsa, again mp3 sounds ok.

btw. https://github.com/dr-soft/mini_al looks great and is in active development, perhaps your oto player can benefit from that library, my bindings are low level, I didn't figure out how I can implement reader/writer. Single header library, public domain, with plan to support CoreAudio and iOS :)

panic: runtime error: index out of range in maindata.readHuffman

Hello.

I found a index out of range bug in go-mp3.

Please confirm.

Thanks.

reproduce code:

package mp3

import (
	"bytes"
	"testing"
)

type bytesReadCloser struct {
	*bytes.Reader
}

func (b *bytesReadCloser) Close() error {
	return nil
}

func TestFuzzingIssue3(t *testing.T) {
	inputs := []string{
			"\xff\xfa%00000000000000000" +
			"000000000000s0000000" +
			"00000000000000000000" +
			"00000000000000000000" +
			"00000000000000000000" +
			"00000000000000000000",
	}
	for _, input := range inputs {
		b := &bytesReadCloser{bytes.NewReader([]byte(input))}
		_, _ = NewDecoder(b)
	}
}
panic: runtime error: index out of range [recovered]
	panic: runtime error: index out of range

goroutine 5 [running]:
panic(0x500300, 0xc42000a120)
	/usr/lib/go-1.7/src/runtime/panic.go:500 +0x1a1
testing.tRunner.func1(0xc4200683c0)
	/usr/lib/go-1.7/src/testing/testing.go:579 +0x25d
panic(0x500300, 0xc42000a120)
	/usr/lib/go-1.7/src/runtime/panic.go:458 +0x243
github.com/hajimehoshi/go-mp3/internal/maindata.readHuffman(0xc420012450, 0xfffa2530, 0xc420080000, 0xc420082000, 0xdbd, 0x1, 0x1, 0x0, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/maindata/huffman.go:76 +0x27a
github.com/hajimehoshi/go-mp3/internal/maindata.Read(0x7f8624321230, 0xc420012420, 0x0, 0x7f86fffa2530, 0xc420080000, 0x0, 0x0, 0xc42000a590, 0x8)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/maindata/maindata.go:152 +0x417
github.com/hajimehoshi/go-mp3/internal/frame.Read(0x59c420, 0xc420012420, 0x0, 0x0, 0x3, 0x3, 0x3, 0x8)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:97 +0x2f7
github.com/hajimehoshi/go-mp3.(*Decoder).readFrame(0xc42004c2a0, 0x0, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/decode.go:41 +0x59
github.com/hajimehoshi/go-mp3.NewDecoder(0x59cb20, 0xc420026028, 0x78, 0xc42007e000, 0x78)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/decode.go:207 +0x102
github.com/hajimehoshi/go-mp3.TestFuzzingIssue3(0xc4200683c0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/fuzzing_test.go:27 +0x11c
testing.tRunner(0xc4200683c0, 0x52f068)
	/usr/lib/go-1.7/src/testing/testing.go:610 +0x81
created by testing.(*T).Run
	/usr/lib/go-1.7/src/testing/testing.go:646 +0x2ec

zc use questions

Hi,

I Am curious about usage of go-mp3 in zikichombo.org/codec or zikichombo.org/ext.

Some questions about how this might be done, or if it is appropriate.

  1. Do you intend to keep it pure Go?
  2. zc currently has a standard shared author BSD license, and we are careful about transitive licensing via imports, as is being discussed here

Best,
Scott

Missing "oto"

Where is "oto" from example code?
"github.com/hajimehoshi/oto"

Thank you

Save decoded mp3 to wave file

I would like to convert audio files mp3 to wav and wav to mp3 with pure go.

I guess save bytes to file with .wav extension is not what I should do. Pure go mean not using lame or ffmpeg, other CLI tools... I want get a go app that can convert and mix audio files with export both formats. But I can't figure out how it do

Multiple crashers

Decode crushes on flowing inputs:

Found with go-fuzz

"\xff\xfa500000000000\xff\xff0000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"0000"
"\xff\xfb\x100004000094\xff000000" +
"00000000000000000000" +
"00\u007f0\xff\xee\u007f\xff\xee\u007f\xff\xff\u007f\xff\xff\xee\u007f\xff\xff0" +
"\xff\xff00\xff\xee\u007f\xff0000\u007f00\xff00\xee0" +
"000\xff000\xff\xff\xee\u007f0\xff0000\u007f\xff0" +
"00\xff0"
"\xff\xfb\x100004000094\xff000000" +
"00000000000000000000" +
"00\u007f0\xff\xee\u007f\xff\xee\u007f\xff\xff\u007f\xff\xff\xee\u007f\xff\xff\u007f" +
"\xff\xff\u007f0\xff\xee\u007f\xff0000\u007f00\xff\xff\xee\xee0" +
"0\xee\u007f\xff000\xff\xff\xee\u007f0\xff0000\u007f\xff0" +
"0\xff\xff0"
"\xff\xfa\x1000000000000000000" +
"00000000000000000000" +
"000000000000000000\xff\xff" +
"0\u007f\xff\xff\u007f\xff\xff\u007f\xff\xff\xfc0\xff\xef\xbf0\xef\xbf00" +
"0\xff\xee\u007f\xff\xff\u007f\xff\xff\xee\u007f\xff\xff\u007f\xff\xff\u007f\xff00" +
"\xff\xff00"
"\xff\xfa00000031000000000n" +
"s0f00000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000\u007f\xff\xff000\xff\xee"
"\xff\xfa\x1000000000000000000" +
"00000000000000000000" +
"00000000000000000000" +
"00000000000000\xbf0\xef\xbf00" +
"0\xff\xee0\xff\xff\u007f\xff\xff\xee\u007f\xff\xff\u007f\xff\xff\u007f\xff00" +
"\xff0\xee0"
"\xff\xfa\x100000050000000000\u007f" +
"00000000000000000000" +
"0000000000\xee\u007f0\xff\xff\xff\xff\u007f\xff\xff" +
"\xee\u007f\xff\xff\u007f\xff\xff\u007f\xff\xff\xfc\xee\xff\xef\xbf0\xef\xbf00" +
"0\xff\xee\u007f\xff\xff\u007f\xff\xff\xee\u007f\xff\xff\u007f\xff\xff\u007f\xff0\t" +
"\xff\xff\xee\xee"

only layer3 (want 1; got 3) is supported!

Steps to reproduce:

  1. Open this file Sleep Away.mp3
  2. Call mp3.Decode() on the file

Expected result:

Decoding file successfully

Actual result:

The function returns an error saying mp3: mp3: only layer3 (want 1; got 3) is supported

Notes:

I using a version of go-mp3 is v0.3.2
I use the mp3 file inside the same issue #9 that is decoded successfully

panic: runtime error: index out of range in stereoProcessIntensityLong

Hello.

I found a index out of range bug in go-mp3.

Looks similar to #23 problem.

Please confirm.

Thanks.

reproduce code:

package mp3

import (
	"bytes"
	"testing"
)

type bytesReadCloser struct {
	*bytes.Reader
}

func (b *bytesReadCloser) Close() error {
	return nil
}

func TestFuzzing(t *testing.T) {
	inputs := []string{
		"\xff\xfb0x000000\xf9000\x00\x030000" +
		"000000000000\xf70000000" +
		"\x900000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"00000000000000000000" +
		"0000000000000",
	}
	for _, input := range inputs {
		b := &bytesReadCloser{bytes.NewReader([]byte(input))}
		_, _ = NewDecoder(b)
	}
}

Log

--- FAIL: TestFuzzing (0.00s)
panic: runtime error: index out of range [recovered]
	panic: runtime error: index out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc42004c680)
	/usr/lib/go-1.8/src/testing/testing.go:622 +0x29d
panic(0x527020, 0x5e99f0)
	/usr/lib/go-1.8/src/runtime/panic.go:489 +0x2cf
github.com/hajimehoshi/go-mp3/internal/frame.(*Frame).stereoProcessIntensityLong(0xc4200b6000, 0x0, 0x8)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:309 +0x1ed
github.com/hajimehoshi/go-mp3/internal/frame.(*Frame).stereo(0xc4200b6000, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:406 +0x45f
github.com/hajimehoshi/go-mp3/internal/frame.(*Frame).Decode(0xc4200b6000, 0xc4200149c0, 0x0, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/internal/frame/frame.go:126 +0x119
github.com/hajimehoshi/go-mp3.(*Decoder).readFrame(0xc420018a20, 0x0, 0x0)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/decode.go:52 +0x17f
github.com/hajimehoshi/go-mp3.NewDecoder(0x5d8ca0, 0xc42000c098, 0x139, 0xc420075040, 0x139)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/decode.go:207 +0xc0
github.com/hajimehoshi/go-mp3.TestFuzzing(0xc42004c680)
	/home/karas/go/src/github.com/hajimehoshi/go-mp3/fuzzing_test.go:38 +0x126
testing.tRunner(0xc42004c680, 0x554b00)
	/usr/lib/go-1.8/src/testing/testing.go:657 +0x96
created by testing.(*T).Run
	/usr/lib/go-1.8/src/testing/testing.go:697 +0x2ca
exit status 2
FAIL	github.com/hajimehoshi/go-mp3	0.006s

Opened Context consumes 100% CPU

Hi @hajimehoshi ,

First of all, thanks a lot for your awesome work on go-mp3.

I'm on linux, and while trying it out, I noticed that after the oto.Context has been created, CPU is always at 100% load. E.g. I was following your example https://github.com/hajimehoshi/go-mp3/blob/master/example/main.go , and wrote a function which just plays some mp3 file once:

func playBeep() error {
	f, err := assets.Open("beep.mp3")
	if err != nil {
		return err
	}
	defer f.Close()

	d, err := mp3.NewDecoder(f)
	if err != nil {
		return err
	}
	defer d.Close()

	p, err := oto.NewPlayer(d.SampleRate(), 2, 2, 8192)
	if err != nil {
		return err
	}
	defer p.Close()

	if _, err := io.Copy(p, d); err != nil {
		return err
	}
	return nil
}

And I noticed that after this function was called the first time, my app starts consuming 100% CPU. After some investigation, I found out that oto.NewPlayer() creates a context which is then never closed, and this context is what actually consumes CPU.

However, the code suggests that the context should only be created once: https://github.com/hajimehoshi/oto/blob/master/context.go#L59-L61

	if theContext != nil {
		panic("oto: NewContext can be called only once")
	}

And I noticed that theContext isn't really used anywhere, it only prevents contexts from being created more than once. So I tried to remove that limitation (thus allowing context to be create multiple times), so my playBeep function looks as follows:

func playBeep() error {
	f, err := assets.Open("beep.mp3")
	if err != nil {
		return err
	}
	defer f.Close()

	d, err := mp3.NewDecoder(f)
	if err != nil {
		return err
	}
	defer d.Close()

	c, err := oto.NewContext(d.SampleRate(), 2, 2, 8192)
	if err != nil {
		return err
	}
	defer c.Close()

	p := c.NewPlayer()
	defer p.Close()

	if _, err := io.Copy(p, d); err != nil {
		return err
	}
	return nil
}

And it seems to work fine: plays the sound ever time it's called, and CPU is okay. So, what was the reason for that theContext?

Crashes with some MP3's

Decoding crashes with the MP3 from here and other MP3's from that site: http://soundbible.com/2122-40-Smith-Wesson.html

signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4a9fa7]

goroutine 1 [running]:
github.com/hajimehoshi/go-mp3.(*source).readNextFrame(0xc420098180, 0x0, 0xc4200a2018, 0x7f5e2f9c0f70, 0xc4200a2018, 0x1)
        /home/faiface/go/src/github.com/hajimehoshi/go-mp3/read.go:42 +0x67
github.com/hajimehoshi/go-mp3.NewDecoder(0x506580, 0xc4200a2018, 0xc420063ea8, 0xc4200a2018, 0x0)
        /home/faiface/go/src/github.com/hajimehoshi/go-mp3/decode.go:291 +0x133
github.com/faiface/beep/mp3.Decode(0x506580, 0xc4200a2018, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/faiface/go/src/github.com/faiface/beep/mp3/decode.go:30 +0x7e

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.