Created
February 11, 2024 20:18
-
-
Save Luigi-Pizzolito/4d8c5b97536b3059e6f93aac05f1449f to your computer and use it in GitHub Desktop.
Plays a raw wav file from stdin, mono, 16kHz.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"time" | |
"os" | |
"io/ioutil" | |
"github.com/ebitengine/oto/v3" | |
"github.com/youpy/go-wav" | |
) | |
func main() { | |
// Read the WAV file from stdin | |
rawBytes, err := ioutil.ReadAll(os.Stdin) | |
if err != nil { | |
panic("Failed to read WAV input: "+err.Error()) | |
} | |
// Convert the pure bytes into a reader object that can be used with the mp3 decoder | |
// fileBytesReader := bytes.NewReader(fileBytes) | |
fileBytesReader := bytes.NewReader(rawBytes) | |
// Decode file | |
decodedWav := wav.NewReader(fileBytesReader) | |
// Prepare an Oto context (this will use your default audio device) that will | |
// play all our sounds. Its configuration can't be changed later. | |
op := &oto.NewContextOptions{} | |
// Usually 44100 or 48000. Other values might cause distortions in Oto | |
op.SampleRate = 16000 | |
// Number of channels (aka locations) to play sounds from. Either 1 or 2. | |
// 1 is mono sound, and 2 is stereo (most speakers are stereo). | |
op.ChannelCount = 1 | |
// Format of the source. go-mp3's format is signed 16bit integers. | |
op.Format = oto.FormatSignedInt16LE | |
// Remember that you should **not** create more than one context | |
otoCtx, readyChan, err := oto.NewContext(op) | |
if err != nil { | |
panic("oto.NewContext failed: " + err.Error()) | |
} | |
// It might take a bit for the hardware audio devices to be ready, so we wait on the channel. | |
<-readyChan | |
// Create a new 'player' that will handle our sound. Paused by default. | |
player := otoCtx.NewPlayer(decodedWav) | |
// Play starts playing the sound and returns without waiting for it (Play() is async). | |
player.Play() | |
// We can wait for the sound to finish playing using something like this | |
for player.IsPlaying() { | |
time.Sleep(time.Millisecond) | |
} | |
time.Sleep(time.Millisecond*100) | |
// If you don't want the player/sound anymore simply close | |
err = player.Close() | |
if err != nil { | |
panic("player.Close failed: " + err.Error()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment