Giter VIP home page Giter VIP logo

beep's People

Contributors

alextopher avatar asday avatar avivklas avatar cebarks avatar christopher-dg avatar cswank avatar deryrahman avatar dusk125 avatar duysqubix avatar dxbednarczyk avatar eula01 avatar faiface avatar hundemeier avatar hyperturtle avatar ilyapashuk avatar jboverfelt avatar jwangsadinata avatar jypelle avatar lordwelch avatar markkremer avatar mewmew avatar nhalstead avatar rsp9u avatar tslocum 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

beep's Issues

Error for each supported audio file type

I have tried running functional audio files for a .flac, .mp3 and .wav but receive different errors for each one. My code is pretty much the same for the 3 different tests:

package main

import(
  "fmt"
  "time"
  "os"
  "github.com/faiface/beep/<file type>"
  "github.com/faiface/beep/speaker"
)

func main() {
  openFile, openFileErr := os.Open("<path/to/file>")
  if openFileErr != nil {
    fmt.Println("FILE OPEN ERROR", openFileErr)
    return
  }
  streamer, format, streamerErr := <file type>.Decode(openFile)
  if streamerErr != nil {
    fmt.Println("AUDIO STREAMER ERROR", streamerErr)
    return
  }
  speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
  speaker.Play(streamer)
  select{}
}

Expected:
Audio plays normally.

WAV Result:
wav: missing data chunk marker

MP3 Result:
mp3: mp3: only layer3 (want 1; got 3) is supported

Flac Result:
flac: flac.parseStreamInfo: invalid FLAC signature; expected "fLaC", got "RIFF"

Here are the files for your own use:
Flac file
MP3 file
WAV file

All the files are generated by the IBM Watson text-to-speech API and run fine on my machine. All error messages occur within the AUDIO STREAMER ERROR block. Is this a bug? Thanks!

Run beep/examples/playing didn't hear the beep

platform:mac os x 10.12.6

if i put this in the end ,it works:
time.Sleep(time.Millisecond*100)

it seems like if the sound was too short , like a beep,the seq streamer returned before the sound actually been played.

Did someone else have the same problem?

Pattern for "stopping" sound

Hi @faiface, thank you so much for this library. It is an incredible work of code and performs really beautifully.

One thing I couldn't figure out from reading your docs (which are also well written btw!) is whether there is a pattern to stop / cancel a streamer?

In the most basic case, something like this:

done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
	done <- true
})))

time.Sleep(1 * time.Second)
// stop streamer during its playback?

<-done

Even if there is a hacky way to do this (e.g. maybe setting the volume to zero and still letting it play out?), I'd be very grateful for any advice.

Re-playing a stream using speaker?

I'm trying to integrate the beep library in a game, but I have a hard time to find information how to play a sound over and over again. I want to load resources during startup and currently I'm saving the decoded streams. Then I just want to call speaker.Play(stream) upon an event. But that only plays the sound once. Calling it again does nothing.

Any example how to replay and re-use streams?

This is my test-code for playing mp3/wav:


  type sound struct {
	sounds map[string]beep.StreamSeekCloser
   }

    func (s *sound) create() {
	s.sounds = make(map[string]beep.StreamSeekCloser)

	for _, file := range gSoundFiles {
		f, _ := os.Open(fmt.Sprintf("assets/sounds/%v", file))
		if strings.Contains(file, "mp3") {
			name := strings.TrimSuffix(file, ".mp3")
			stream, format, err := mp3.Decode(f)
			if err != nil {
				panic("Failed to load sound")
			}
			s.sounds[name] = stream
			speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
		} else if strings.Contains(file, "wav") {
			name := strings.TrimSuffix(file, ".wav")
			stream, format, err := wav.Decode(f)
			if err != nil {
				panic("Failed to load sound")
			}
			s.sounds[name] = stream
			speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
		}
	}
    }

    func (s *sound) play(name string) {
     	speaker.Play(s.sounds[name])
    }

Remove ReadSeeker assertions

I want to use this to play a stream over HTTP, but the library only supports ReadClosers that are also ReadSeekers. If I comment out the type assertion here I'm able to play a flac stream from my other machine without any problems.

Calling any Seek() methods without seek support should return an error (not cause a panic), but the library shouldn't require it when users don't call those methods.

greetings

Hi,

I couldn't find another way to contact you, so I'm contacting you as beep author by filing an issue.

Great work on beep!

I'm writing to ask your consideration in collaborating or otherwise engaging in, perhaps as a
guiding member in the ZikiChombo open source project hosted at http://zikichombo.org
(and GitHub.com/zikichombo) as there is a lot of overlap with beep and interfacing with beep-level like functionality.

Thanks for the great project.
Scott

Seeking causes different panics

Steps to reproduce:

  1. Create a stream and play it
  2. Seek it

Example:
Note: this example uses the following mp3 file: http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/cortex/Cortex_054.mp3

package main

import (
	"os"
	"time"
	//"fmt"
	"github.com/faiface/beep/mp3"
	"github.com/faiface/beep/speaker"
)

func main() {
	f, _ := os.Open("Cortex_054.mp3")
	stream, format, _ := mp3.Decode(f)

	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	speaker.Play(stream)
        
        /* Uncomment to get a stack overflow, leave it commented for a bad pointer panic */
	//fmt.Printf("Len: %d, Pos: %d\n", stream.Len(), stream.Position())
	stream.Seek(10)
	time.Sleep(time.Hour)
}

Expected result:
The playback starts, then moves back to position 10 and continues for up to an hour.

Actual result:
Two panics may happen:

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

or

runtime: writebarrierptr *0xc042018150 = 0x4
fatal error: bad pointer in write barrier

Audio blocking

First of all, I dont speak english (i'm brazilian)
Well, I'm using this code

package main

import "os"
import "time"
import "github.com/faiface/beep/mp3"
import "github.com/faiface/beep/speaker"

func main() {
	f, _ := os.Open("test.mp3")
	s, format, _ := mp3.Decode(f)
	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	speaker.Play(s)
	select {}
}

And when the program is in the background the audio stops and returns successively.

Method for closing the context and hence releasing the device

The audio device never releases after calling speaker.Init()
I suggest to extract the following code from Init():

if player != nil {
	done <- struct{}{}
	player.Close()
	context.Close()
}

to a separated public method.

What do you think?

BTW, great work! This pkg is the cornerstone of a project I'm working on

Can't call speaker.Lock() from within beep.Callback() function

Hey, there. It doesn't seem to be possible to call speaker.Lock() from within a Callback() function, which is understandable, as that keeps it from accessing all streamers, including the callback streamer. However, this doesn't seem to be documented anywhere, so it might be a good idea to add this tidbit to the documentation for speaker.Lock().

Flac format requires mewkiz/flac

Hey, it seems that flac support requires go get github.com/mewkiz/flac, but that's not mentioned in the dependencies / requirements.

How to determin if the resource is busy

When I use PJSIP to implement VoIP application and use 'beep' play wav file in another application, it returns 'resource busy'. Is there any function or error return to determin if the audio resource is busy.

ALSA lib ../../../alsa-lib-1.1.0/src/pcm/pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
aplay: main:722: audio open error: Device or resource busy

Add callback to stream that will be called a multiple of bufferlengths before the stream finishes.

When using a queue or sequence like in the beep examples it is possible to (dynamically) add streams without pausing playback (gapless). Would it be possible to get notified right before the end of a stream so an new one can be added to the queue without experiencing any pauses? So, a notification 1 or more bufferlengths away from the end of a stream so we have enough time to add a new one?

speaker.update() is not a public function?

The update() function on speaker.go is currently a private function. I was wondering whether this should be exposed as a public function?

The use case I was thinking of was actually integrating pixel and beep, like how to mute a song that is playing through a button press. My thoughts on doing this were something like this, inside the pixel run() function:

song, _ := os.Open("song.mp3")
s, format, _ := mp3.Decode(song)

// volume control
vc := &effects.Volume{
    Streamer: beep.Loop(-1, s),
    Base:     2,
    Volume:   0,
    Silent:   false,
}

// speaker init and play
...

for !win.Closed() {
    // M to mute
    if win.JustPressed(pixelgl.KeyM) {
        speaker.Lock()
        vc.Silent = true
        speaker.Unlock()
    }
    // N to unmute
    if win.JustPressed(pixelgl.KeyN) {
        speaker.Lock()
        vc.Silent = false
        speaker.Unlock()
    }

    win.Update()
    speaker.Update() // currently still a private function
}

The above is the rough idea I had in mind, at least update() should be able to be exposed as well? This is still some rough ideas and probably would not work now, but I can certainly implement it and see what happens. If you have a suggested way on how to do what I wanted to achieve, any tips/suggestions will be highly appreciated.

How to apply effects

I can't find info how to apply effects to streams and I don't have enough go knowledge to reverse engineer usage from source :)

I tried this with no luck:

package main

import "os"
import "time"
import "github.com/faiface/beep"
import "github.com/faiface/beep/wav"
import "github.com/faiface/beep/speaker"
import "github.com/faiface/beep/effects"

func main() {

  f, _ := os.Open("greek555.wav")
  s, format, _ := wav.Decode(f)

  s2 := effects.Volume{
    Streamer: s,
    Base:     2,
    Volume:   -2000,
  }

  speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
  done := make(chan struct{})

  speaker.Play(beep.Seq(s2, beep.Callback(func() {
    close(done)
  })))

  <-done

}

I'm getting error:

./sound.go:24:24: cannot use s2 (type effects.Volume) as type beep.Streamer in argument to beep.Seq:
effects.Volume does not implement beep.Streamer (Err method has pointer receiver)

So how do I apply Volume effect to a stream?

Implementation of Beep with GLHF gets stuck during sound

Ive tried using Beep to play sounds aswell as rendering images with GLHF but i cant seem to get it working.

Once the sound starts playing the images stop rendering as its on the same thread, ive tried using
mainthread.Run(Sound.PlaySound)
and
mainthread.CallNonBlock(Sound.PlaySound)
But both wont work to make audio and video work together
If im doing this totally wrong please tell me

Why cannot this mp3 file play?

It can play your""sample1.mp3, but cannot play the attachment mp3 file(please unzip first).
error:
`fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.Play(0x4e9de5, 0x9)
D:/Code/IdeaProjects/Go/test/main/main.go:39 +0x292`

ok.zip

Error in mp3.Seeker implementation

The Seeker implementation of the mp3 decoder is not fully correct.
The Position() method returns incorrect values after seeking.

f, err := os.Open("./test.mp3")
if err != nil {
	log.Fatal(err)
}
s, format, err := mp3.Decode(f)
if err != nil {
	log.Fatal(err)
}
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
speaker.Play(s)
fmt.Println("Position:", s.Position())
time.Sleep(3 * time.Second)
s.Seek(0)
fmt.Println("Position:", s.Position())
select {}

The above example works fine with the wav-decoder.

Expected output:

Position: 0
Position: 0

Real output (with my mp3 testfile):

Position: 0
Position: 145530

A quick fix would be to add the following line to

mp3/decode.go -> Seek()

d.pos = int64(p)*gomp3BytesPerFrame

But I do not know if this has sideffects with the go-mp3 library.

Features

Here we have the new repo, hope you like the new name!

In the old repo, we had an issue where we discussed the progress and features. I liked this approach, so I'm bringing it here too.

The methodology remains:

  1. Look through the list of features below.
  2. Select one which you'd like to implement.
  3. Post a comment with:
    a) The feature.
    b) The minimum time it will take you from posting the comment. (I'll be surprised if I finish it by this time.)
    c) The maximum time it will take you from posting the comment. (I'll be embarrassed if I don't finish it by this time.)
  4. Do the work.

The structured list of features

  • Streamer interface
  • Buffer struct (something like bytes.Buffer but for samples, able to multiple Streamers)
    • Format struct (sample rate, number of channels, ...)
  • Streamers (not created from other Streamers)
    • Silence
    • Callback
    • Iterate
  • Compositors
    • Take
    • Loop
    • Ctrl
    • Resample
    • Seq
    • Mix
    • Sched
    • Dup
  • speaker playback package
  • Decoders/Encoders
    • wav
      • Decode
      • Encode
    • ogg
      • Decode
      • Encode
    • mp3
      • Decode
      • Encode
    • flac
      • Decode
      • Encode
  • effects package
    • Gain
    • Volume
    • Pan
    • Positional
    • Distortion
    • Equalizer
    • ...

Missing Documentation for Effects

Hello, i am trying to use some effects on my Stream but i am unable to find documentation about the effects aspect of this libary. Could you provide me with a basic use case ? Im currently writing more examples for this libary ( #23 ). Im unable to find more infos in the godoc

Feature Request: Be able to cancel a Seq

Hello!

Beep has been fantastic to use. However I'm having some difficulty with the following situation.

I have a Seq of a StreamSeekCloser followed by a BeepCallback() to tell me when the audio file is done. Sometimes I'd like to stop streaming early, but If I close the StreamSeekCloser then my BeepCallback gets called.

I took a look at the implementation of Seq and it doesn't look like I can alter the items of the sequence after creation, which means I can't purposefully remove the BeepCallback() and then close the stream.

Would you be open to adding the ability to cancel a Seq which would cancel the current stream and then not run any of the other streams?

Thanks!

Previous audio overwritten by new audio

This a question on how to implement beep so that each new audio play does not overwrite the previous one. I tried to figure it out through the documentation but my ignorance on how audio works has brought me to a roadblock.

I have a game I've been writing here, https://github.com/FuzzyStatic/shape-wars, and I've been using the example you have in the README (https://github.com/FuzzyStatic/shape-wars/blob/master/audio.go). It seems any time I play a new audio file the previous audio stops or goes silent.

Any information you can give me is greatly appreciated!

Possible wrong conversion in wav/decode.go

Hi!
Thanks for your library. I've been wandering the wave decoder and stumble upon
your normalization process which, to me, is a bit off (litterally ;-)

Running your computation (from line 234, 235) in the GoPlayground:

package main
import "fmt"
func main() {
    b := []byte{255,127,0,128}
    shift := int16(1 << 8)
    norm := float64(1 << 15 - 1)
    v1 := float64(int16(b[0]) + int16(b[1]) * shift) / norm
    v2 := float64(int16(b[2]) + int16(b[3]) * shift) / norm
    fmt.Println(v1, ";", v2)
}

You'll get: 1 ; -1.000030518509476
The negative value "overshoot"

Setting: norm := float64(1 << 15)
And you'll get : 0.999969482421875 ; -1

This is the correct range right?
If so, all your computions are affected (not only the 16-bits 2 channels).

Also I suspect line 237 should be:
"case d.h.BitsPerSample == 24 && d.h.NumChans == 1:"
And not
">= 1"
because currently you are converting a stereo 24bits to a mono stream ;-)

Cheers!

Gain not working

Audio sounds the same...

package main

import (
    "log"
    "os"
    "time"

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

func main() {
    // Open first sample File
    fileName := "somesong.mp3" // os.Args[1]

    f, err := os.Open(fileName)

    // Check for errors when opening the file
    if err != nil {
        log.Fatal(err)
    }

    // Decode the .mp3 File, if you have a .wav file, use wav.Decode(f)
    s, _, _ := mp3.Decode(f)

    start := int(float64(s.Len()) * (2 / 5)) //  start on minute 2 of 5 minute song
    s.Seek(start)

    speed := 1.0                                 // 0.75
    sampleRate := beep.SampleRate(44100 * speed) // integer

    // Init the Speaker with the SampleRate of the format and a buffer size of 1/10s
    speaker.Init(sampleRate, sampleRate.N(time.Second/10))

    // Channel, which will signal the end of the playback.
    playing := make(chan struct{})

    // Now we Play our Streamer on the Speaker
    speaker.Play(
        beep.Seq(
            effects.Gain{
                Streamer: s,
                Gain:     1.9,
            }.Streamer,
            // []beep.Streamer{v1}...,
            beep.Callback(func() {
                // Callback after the stream Ends
                close(playing)
            }),
        ),
    )

    <-playing
}

fatal error: all goroutines are asleep - deadlock!

I must have done something wrong in the order of operations. Here's my code to listen to myfile.mp3:

f, _ := os.Open("myfile.mp3)
s, format, _ := mp3.Decode(f)

speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

done := make(chan struct{})

speaker.Play(beep.Seq(s, beep.Callback(func() {
    close(done)
})))

<-done

Add some Examples

Hello,

at the moment I enjoy your library very much. But a few examples would help a lot to get started quickly. Some Code Examples for the Mixer and basic .mp3/.wav playing

Duration of audiostream is 0

i try to stream audio from the internet and it is playing nicely, but i can not calculate the duration of the stream (it's actually a podcast). I set up the playback like this:

`

func playRemoteFile() {
resp, err := http.Get("https://traffic.libsyn.com/wakingup/Making_Sense_156_Nicholas_Christakis.mp3")


if err != nil {
	log.Fatal(err)
}

streamer, format, err := mp3.Decode(resp.Body)
if err != nil {
	log.Fatal(err)
}
defer streamer.Close()

speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

ctrlStreamer := &beep.Ctrl{Streamer: streamer, Paused: false}

done := make(chan bool)
speaker.Play(beep.Seq(ctrlStreamer, beep.Callback(func() {
	done <- true
})))

for {
	select {
	case <-done:
		return
	case <-time.After(time.Second):
		speaker.Lock()
		fmt.Printf("time elapsed: %d of %d\n", format.SampleRate.D(streamer.Position()), format.SampleRate.D(streamer.Len()))
		speaker.Unlock()
	}
}

}

`

streamer.Len() returns 0.
the response contains only the content length. Is it possible to somehow calculate the duration?

Ctrl and Loop

I am trying to pause a stream playing through beep.Loop, but when I attempt my program hangs. I am also using termui which makes it a little hard to debug.

Is this not supported?

I will post my code just in case I have messed something up. This is my first foray into go so it is quite possible that it is my fault.

ctrl := &beep.Ctrl{Streamer: beep.Loop(1, stream)}

	// Init the Speaker with the SampleRate of the format and a buffer size of 1/10s
	speaker.Clear()
	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

	// Internal channel, which will signal the end of the playback.
	internalPlay := make(chan struct{})

	speaker.Play(beep.Seq(ctrl, beep.Callback(func() {
		close(internalPlay)
	})))

And then later:

		case stm := <-playControl:
			switch stm {
			case "pause":
				speaker.Lock()
				if ctrl.Paused {
					ctrl.Paused = false
				} else {
					ctrl.Paused = true
				}
				speaker.Unlock()

two different audio streams at the same time?

Okay, so I know mixers are a thing in this library but what I need to do doesn't appear to be covered by that.

So let's say I have a game with background music playing, but I want to do sound effects when something happens, but I don't want the music to be interrupted/restarted and I want it to continue playing but also play the sound effect when it's needed

how would I go about accomplishing this?

Struggling with Ctrl

I'm sure I'm doing something wrong, but I'd appreciate some help with the code below.

Basically, no matter what I do. Ctrl doesn't pause nor set the volume of the streamer.
Furthermore, the audio is not resampled to the file's sampling rate and thus stuck at 44100

type Audio struct {
	filename string
	streamer beep.StreamSeekCloser
	format   beep.SampleRate
}

var monkey Audio

func init() {
	sr := beep.SampleRate(44100)
	speaker.Init(sr, sr.N(time.Second/10))
}

func main() {
	monkey.filename = "monkey.mp3"
	monkey.startMusic()
	monkey.test()
}

func (a *Audio) startMusic() {
	f, err := os.Open(a.filename)
	if err != nil {
		log.Fatal(err)
	}

	streamer, format, err := mp3.Decode(f)
	if err != nil {
		log.Fatal(err)
	}

	sr := format.SampleRate * 2

	resampled := beep.Resample(4, format.SampleRate, sr, streamer)

	speaker.Play(resampled)
	a.streamer = streamer
	a.format = sr
}

func (a *Audio) test() {
	ctrl := &beep.Ctrl{Streamer: beep.Loop(-1, a.streamer), Paused: false}
	volume := &effects.Volume{
		Streamer: ctrl,
		Base:     2,
		Volume:   0,
		Silent:   false,
	}

	speaker.Lock()
	volume.Volume -= 1.5 // <-- this right here
	ctrl.Paused = !ctrl.Paused
	speaker.Unlock()

	for {
		fmt.Print("Press [ENTER] to pause/resume. ")
		fmt.Scanln()

		speaker.Lock()
		ctrl.Paused = !ctrl.Paused
		volume.Volume += 0.5
		speaker.Unlock()
	}
}

AAC Decode

Any plans to introduce an AAC Decoder?

Buffer.Pop pops n bytes instead of n samples

The documentation for Buffer.Pop states:

Pop removes n samples from the beginning of the Buffer.

But this isn't the case. In my test it only pops half the number of samples.

This is the current source:

// Buffer is a storage for audio data. You can think of it as a bytes.Buffer for audio samples.
type Buffer struct {
	f    Format
	data []byte
	tmp  []byte
}

// ...

// Pop removes n samples from the beginning of the Buffer.
//
// Existing Streamers are not affected.
func (b *Buffer) Pop(n int) {
	b.data = b.data[n:]
}

b.data is of type []byte but Pop doesn't take the sample length into account (1 sample has a width of 2 bytes in my test). I think it should be implemented something like this instead:

func (b *Buffer) Pop(n int) {
	b.data = b.data[n*b.f.Width():]
}

Minimizing the bufferSize

I've been working on a super simple midi-based synthesizer based heavily on your approach to handling the audio signal. I'd like to keep working on it but I can't seem to get the buffersize down enough so that the latency isn't so noticeable. I can get it down to about 22 milliseconds but any lower and there's a clicking sound. Do you have an idea as to why the smaller buffer sizes become problematic?

My start is here, if you're curious:
https://github.com/lucianthorr/aja/blob/3ee2d82b74f5ab6755732f9f30a0899d18cc2464/main.go#L24

Runtime out of memory

Hi, I'm trying to use .go as .so lib which then is imported to python.

extsoundmix.go

//extsoundmix.go
package main

import (
	"C"
	"log"
	"os"
	"time"

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

//export PlaySong
func PlaySong(s string) {
	f, err := os.Open(s)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	streamer, format, err := mp3.Decode(f)
	if err != nil {
		log.Fatal(err)
	}

	defer streamer.Close()

	done := make(chan bool)
	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	speaker.Play(beep.Seq(streamer, beep.Callback(func() {
		done <- true
	})))
	<-done
	// defer f.Close()
}

func main() {
	// PlaySong("/home/dfsad/Downloads/black-alert.mp3")
}

app.py

from ctypes import cdll

lib = cdll.LoadLibrary('/home/dfsad/go/src/extsound/extsoundmix.so')
print("Loaded go generated SO library")
result = lib.PlaySong("/home/dfsad/Downloads/black-alert.mp3")


runtime: out of memory: cannot allocate 140648171077632-byte block (66748416 in use)
fatal error: out of memory

runtime stack:
runtime.throw(0x7feb2017abc4, 0xd)
	/usr/local/go/src/runtime/panic.go:617 +0x74
runtime.largeAlloc(0x7feb34467ccf, 0x7feb204b0100, 0xc0000b2120)
	/usr/local/go/src/runtime/malloc.go:1057 +0x16d
runtime.mallocgc.func1()
	/usr/local/go/src/runtime/malloc.go:950 +0x48
runtime.systemstack(0x7ffcee70f2e0)
	/usr/local/go/src/runtime/asm_amd64.s:351 +0x63
runtime.mstart()
	/usr/local/go/src/runtime/proc.go:1153

goroutine 17 [running, locked to thread]:
runtime.systemstack_switch()
	/usr/local/go/src/runtime/asm_amd64.s:311 fp=0xc000046920 sp=0xc000046918 pc=0x7feb2011c650
runtime.mallocgc(0x7feb34467ccf, 0x0, 0x7feb18aec900, 0x20300000000000)
	/usr/local/go/src/runtime/malloc.go:949 +0x884 fp=0xc0000469c0 sp=0xc000046920 pc=0x7feb200d4cd4
runtime.rawstring(0x7feb34467ccf, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/string.go:259 +0x51 fp=0xc0000469f0 sp=0xc0000469c0 pc=0x7feb2010c3b1
runtime.rawstringtmp(0x0, 0x7feb34467ccf, 0xc000046af0, 0x7feb200d1fa3, 0x7feb203d18e0, 0x7feb0002fa80, 0x7feb203c66a0)
	/usr/local/go/src/runtime/string.go:123 +0x74 fp=0xc000046a30 sp=0xc0000469f0 pc=0x7feb2010bd74
runtime.concatstrings(0x0, 0xc000046b10, 0x5, 0x5, 0x7feb2017b1e7, 0x10)
	/usr/local/go/src/runtime/string.go:49 +0xb0 fp=0xc000046ac8 sp=0xc000046a30 pc=0x7feb2010b7f0
runtime.concatstring5(0x0, 0x7feb2017995a, 0x4, 0x7feb20179780, 0x1, 0x7feb21580c10, 0x7feb34467cb8, 0x7feb201797b4, 0x2, 0x7feb2017b1e7, ...)
	/usr/local/go/src/runtime/string.go:70 +0x49 fp=0xc000046b08 sp=0xc000046ac8 pc=0x7feb2010bbd9
os.(*PathError).Error(0xc000096180, 0x7feb203ee9c0, 0xc0000d2000)
	/usr/local/go/src/os/error.go:33 +0xad fp=0xc000046b80 sp=0xc000046b08 pc=0x7feb201562fd
fmt.(*pp).handleMethods(0xc0000d2000, 0xc000000076, 0xc000046c01)
	/usr/local/go/src/fmt/print.go:610 +0x198 fp=0xc000046c20 sp=0xc000046b80 pc=0x7feb2015dbb8
fmt.(*pp).printArg(0xc0000d2000, 0x7feb203d18e0, 0xc000096180, 0x7feb00000076)
	/usr/local/go/src/fmt/print.go:699 +0x20c fp=0xc000046cb8 sp=0xc000046c20 pc=0x7feb2015e13c
fmt.(*pp).doPrint(0xc0000d2000, 0xc000046e70, 0x1, 0x1)
	/usr/local/go/src/fmt/print.go:1147 +0xff fp=0xc000046d40 sp=0xc000046cb8 pc=0x7feb20162c4f
fmt.Sprint(0xc000046e70, 0x1, 0x1, 0x0, 0x7feb203f0a60)
	/usr/local/go/src/fmt/print.go:250 +0x54 fp=0xc000046d98 sp=0xc000046d40 pc=0x7feb2015af74
log.Fatal(0xc000046e70, 0x1, 0x1)
	/usr/local/go/src/log/log.go:313 +0x41 fp=0xc000046dd8 sp=0xc000046d98 pc=0x7feb20164131
main.PlaySong(0x7feb21580c10, 0x7feb34467cb8)
	/home/dfsad/go/src/extsound/extsoundmix.go:19 +0xbe fp=0xc000046e90 sp=0xc000046dd8 pc=0x7feb2017858e
main._cgoexpwrap_11df64b4c5a5_PlaySong(0x7feb21580c10, 0x7feb34467cb8)
	_cgo_gotypes.go:45 +0x37 fp=0xc000046eb0 sp=0xc000046e90 pc=0x7feb201784b7
runtime.call32(0x0, 0x7ffcee70f330, 0x7ffcee70f3c0, 0x10)
	/usr/local/go/src/runtime/asm_amd64.s:519 +0x3d fp=0xc000046ee0 sp=0xc000046eb0 pc=0x7feb2011c9ed
runtime.cgocallbackg1(0x0)
	/usr/local/go/src/runtime/cgocall.go:314 +0x17b fp=0xc000046f58 sp=0xc000046ee0 pc=0x7feb200cc80b
runtime.cgocallbackg(0x0)
	/usr/local/go/src/runtime/cgocall.go:191 +0xcb fp=0xc000046fc0 sp=0xc000046f58 pc=0x7feb200cc5eb
runtime.cgocallback_gofunc(0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/asm_amd64.s:773 +0x9a fp=0xc000046fe0 sp=0xc000046fc0 pc=0x7feb2011dffa
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000046fe8 sp=0xc000046fe0 pc=0x7feb2011e751

Control the sound

I setup a mixer playing two mp3 files at the same time. I wish to raise/lower the volume of one of them but cant seems to accomplish that.

Another problem is that I dont understand what values to assign to samples [][2]float64

The code bellow mix two streams at same time and also include my naive not working volume manipulation code. What am I doing wrong?

func main() {
	println("Hi")
	f1, _ := os.Open("data/03_Summertime.mp3")
	s1, format, _ := mp3.Decode(f1)
	f2, _ := os.Open("data/Pink Floyd.mp3")
	s2, format, _ := mp3.Decode(f2)

	v1 := effects.Volume{
		Streamer: s2,
		Base:     2,
		Volume:   -2000,
	}
	samples := [][2]float64{{-50.0, -50.0}, {-50.0, -50.0}}
	v1.Stream(samples)

	mixer := new(beep.Mixer)
	mixer.Play(s1)
	mixer.Play(s2)
	println(mixer.Len())

	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	speaker.Play(mixer)

	select {}
}

Decibel calculation

At hydrogenaudio for ReplayGain they calculate decibels as

10^(gain in dB/20)
Or, in words, ten raised to the power of one-twentieth of replay gain.

So Replay gain only works with their equation.
Is 10^(gain in dB/10) in your documentation wrong or is that just their own calculation.

In order to adjust volume along decibells, pick 10 as the Base and set Volume to dB/10.

packages not found

After downloading go get github.com/faiface/beep and try to run a sample the follow errors appears:

# github.com/rafa-acioly/bitcoin-alert/vendor/github.com/hajimehoshi/oto
vendor/github.com/hajimehoshi/oto/player_linux.go:23:10: fatal error: alsa/asoundlib.h: No such file or directory
 #include <alsa/asoundlib.h>
          ^~~~~~~~~~~~~~~~~~

Tutorial example appears to be broken on linux

When its run i recieve this error:

ALSA lib pcm_dmix.c:1108:(snd_pcm_dmix_open) unable to open slave

However the speedy-player example works but only when installed via go get.

I'm on ubuntu 19.04, running Sway, go 1.12

Edit:

I'm even more confused than before, go build app.go && ./app works without any errors, go run app.go does not

How To Cross-fade

This looks like a great library for playing audio, very simple.
One feature that I don't see by looking through the code or docs is how to cross-fade.
I would like to create an app that plays a playlist, playlist can be modified on the fly.
I would like to cross-fade by x seconds.
Bonus points if we can remove silence or levels under x dB.
Is this possible?
If not, is this something that could be added?

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.