mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
audio/mp3, audio/vorbis, audio/wav: add DecodeWithoutResampling
Updates #2055
This commit is contained in:
parent
298d6488cc
commit
75e84f6eda
@ -57,7 +57,27 @@ func (s *Stream) Length() int64 {
|
||||
return s.orig.Length()
|
||||
}
|
||||
|
||||
// DecodeWithSampleRate decodes MP3 source and returns a decoded stream.
|
||||
// DecodeWithoutResampling decodes an MP3 source and returns a decoded stream.
|
||||
//
|
||||
// DecodeWithoutResampling returns error when decoding fails or IO error happens.
|
||||
//
|
||||
// The returned Stream's Seek is available only when src is an io.Seeker.
|
||||
//
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func DecodeWithoutResampling(src io.Reader) (*Stream, error) {
|
||||
d, err := mp3.NewDecoder(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &Stream{
|
||||
orig: d,
|
||||
resampling: nil,
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// DecodeWithSampleRate decodes an MP3 source and returns a decoded stream.
|
||||
//
|
||||
// DecodeWithSampleRate returns error when decoding fails or IO error happens.
|
||||
//
|
||||
|
@ -139,6 +139,35 @@ func decode(in io.Reader) (*decoded, int, int, error) {
|
||||
return d, r.Channels(), r.SampleRate(), nil
|
||||
}
|
||||
|
||||
// DecodeWithoutResampling decodes Ogg/Vorbis data to playable stream.
|
||||
//
|
||||
// DecodeWithoutResampling returns error when decoding fails or IO error happens.
|
||||
//
|
||||
// The returned Stream's Seek is available only when src is an io.Seeker.
|
||||
//
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func DecodeWithoutResampling(src io.Reader) (*Stream, error) {
|
||||
decoded, channelNum, _, err := decode(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if channelNum != 1 && channelNum != 2 {
|
||||
return nil, fmt.Errorf("vorbis: number of channels must be 1 or 2 but was %d", channelNum)
|
||||
}
|
||||
var s io.ReadSeeker = decoded
|
||||
size := decoded.Length()
|
||||
if channelNum == 1 {
|
||||
s = convert.NewStereo16(s, true, false)
|
||||
size *= 2
|
||||
}
|
||||
stream := &Stream{
|
||||
decoded: s,
|
||||
size: size,
|
||||
}
|
||||
return stream, nil
|
||||
}
|
||||
|
||||
// DecodeWithSampleRate decodes Ogg/Vorbis data to playable stream.
|
||||
//
|
||||
// DecodeWithSampleRate returns error when decoding fails or IO error happens.
|
||||
|
@ -102,6 +102,21 @@ func (s *stream) Seek(offset int64, whence int) (int64, error) {
|
||||
return n - s.headerSize, nil
|
||||
}
|
||||
|
||||
// DecodeWithSampleRate decodes WAV (RIFF) data to playable stream.
|
||||
//
|
||||
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
|
||||
// The format is converted into 2 channels and 16bit.
|
||||
//
|
||||
// DecodeWithSampleRate returns error when decoding fails or IO error happens.
|
||||
//
|
||||
// The returned Stream's Seek is available only when src is an io.Seeker.
|
||||
//
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func DecodeWithoutResampling(src io.Reader) (*Stream, error) {
|
||||
return decode(src, nil)
|
||||
}
|
||||
|
||||
// DecodeWithSampleRate decodes WAV (RIFF) data to playable stream.
|
||||
//
|
||||
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
|
||||
@ -116,6 +131,10 @@ func (s *stream) Seek(offset int64, whence int) (int64, error) {
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) {
|
||||
return decode(src, &sampleRate)
|
||||
}
|
||||
|
||||
func decode(src io.Reader, sampleRate *int) (*Stream, error) {
|
||||
buf := make([]byte, 12)
|
||||
n, err := io.ReadFull(src, buf)
|
||||
if n != len(buf) {
|
||||
@ -182,9 +201,9 @@ chunks:
|
||||
return nil, fmt.Errorf("wav: bits per sample must be 8 or 16 but was %d", bitsPerSample)
|
||||
}
|
||||
origSampleRate := int64(buf[4]) | int64(buf[5])<<8 | int64(buf[6])<<16 | int64(buf[7])<<24
|
||||
if int64(sampleRate) != origSampleRate {
|
||||
if sampleRate != nil && int64(*sampleRate) != origSampleRate {
|
||||
sampleRateFrom = int(origSampleRate)
|
||||
sampleRateTo = sampleRate
|
||||
sampleRateTo = *sampleRate
|
||||
}
|
||||
headerSize += size
|
||||
case bytes.Equal(buf[0:4], []byte("data")):
|
||||
|
@ -134,13 +134,13 @@ func NewPlayer(game *Game, audioContext *audio.Context, musicType musicType) (*P
|
||||
switch musicType {
|
||||
case typeOgg:
|
||||
var err error
|
||||
s, err = vorbis.Decode(audioContext, bytes.NewReader(raudio.Ragtime_ogg))
|
||||
s, err = vorbis.DecodeWithoutResampling(bytes.NewReader(raudio.Ragtime_ogg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case typeMP3:
|
||||
var err error
|
||||
s, err = mp3.Decode(audioContext, bytes.NewReader(raudio.Ragtime_mp3))
|
||||
s, err = mp3.DecodeWithoutResampling(bytes.NewReader(raudio.Ragtime_mp3))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -174,7 +174,7 @@ func NewPlayer(game *Game, audioContext *audio.Context, musicType musicType) (*P
|
||||
|
||||
player.audioPlayer.Play()
|
||||
go func() {
|
||||
s, err := wav.Decode(audioContext, bytes.NewReader(raudio.Jab_wav))
|
||||
s, err := wav.DecodeWithSampleRate(sampleRate, bytes.NewReader(raudio.Jab_wav))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
|
@ -56,7 +56,7 @@ func (g *Game) Update() error {
|
||||
|
||||
// Decode an Ogg file.
|
||||
// oggS is a decoded io.ReadCloser and io.Seeker.
|
||||
oggS, err := vorbis.Decode(g.audioContext, bytes.NewReader(raudio.Ragtime_ogg))
|
||||
oggS, err := vorbis.DecodeWithoutResampling(bytes.NewReader(raudio.Ragtime_ogg))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func (g *Game) initAudio() {
|
||||
|
||||
// Decode an Ogg file.
|
||||
// oggS is a decoded io.ReadCloser and io.Seeker.
|
||||
oggS, err := vorbis.Decode(g.audioContext, bytes.NewReader(raudio.Ragtime_ogg))
|
||||
oggS, err := vorbis.DecodeWithoutResampling(bytes.NewReader(raudio.Ragtime_ogg))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ func (g *Game) init() {
|
||||
g.audioContext = audio.NewContext(48000)
|
||||
}
|
||||
|
||||
jumpD, err := vorbis.DecodeWithSampleRate(48000, bytes.NewReader(raudio.Jump_ogg))
|
||||
jumpD, err := vorbis.DecodeWithoutResampling(bytes.NewReader(raudio.Jump_ogg))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -188,7 +188,7 @@ func (g *Game) init() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
jabD, err := wav.DecodeWithSampleRate(48000, bytes.NewReader(raudio.Jab_wav))
|
||||
jabD, err := wav.DecodeWithoutResampling(bytes.NewReader(raudio.Jab_wav))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -58,11 +58,11 @@ func NewGame() (*Game, error) {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// d, err := wav.Decode(g.audioContext, f)
|
||||
// d, err := wav.DecodeWithoutResampling(f)
|
||||
// ...
|
||||
|
||||
// Decode wav-formatted data and retrieve decoded PCM stream.
|
||||
d, err := wav.Decode(g.audioContext, bytes.NewReader(raudio.Jab_wav))
|
||||
d, err := wav.DecodeWithoutResampling(bytes.NewReader(raudio.Jab_wav))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user