123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // Copyright 2017 The Ebiten Authors
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // Package mp3 provides MP3 decoder.
- //
- // On desktops and mobiles, a pure Go decoder is used.
- // On browsers, a native decoder on the browser is used.
- package mp3
- import (
- "io"
- "github.com/hajimehoshi/go-mp3"
- "github.com/hajimehoshi/ebiten/v2/audio"
- "github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
- )
- // Stream is a decoded stream.
- type Stream struct {
- orig *mp3.Decoder
- resampling *convert.Resampling
- }
- // Read is implementation of io.Reader's Read.
- func (s *Stream) Read(buf []byte) (int, error) {
- if s.resampling != nil {
- return s.resampling.Read(buf)
- }
- return s.orig.Read(buf)
- }
- // Seek is implementation of io.Seeker's Seek.
- func (s *Stream) Seek(offset int64, whence int) (int64, error) {
- if s.resampling != nil {
- return s.resampling.Seek(offset, whence)
- }
- return s.orig.Seek(offset, whence)
- }
- // Length returns the size of decoded stream in bytes.
- func (s *Stream) Length() int64 {
- if s.resampling != nil {
- return s.resampling.Length()
- }
- return s.orig.Length()
- }
- // DecodeWithSampleRate decodes MP3 source and returns a decoded stream.
- //
- // DecodeWithSampleRate returns error when decoding fails or IO error happens.
- //
- // DecodeWithSampleRate automatically resamples the stream to fit with sampleRate if necessary.
- //
- // 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 DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) {
- d, err := mp3.NewDecoder(src)
- if err != nil {
- return nil, err
- }
- var r *convert.Resampling
- if d.SampleRate() != sampleRate {
- r = convert.NewResampling(d, d.Length(), d.SampleRate(), sampleRate)
- }
- s := &Stream{
- orig: d,
- resampling: r,
- }
- return s, nil
- }
- // Decode decodes MP3 source and returns a decoded stream.
- //
- // Decode returns error when decoding fails or IO error happens.
- //
- // Decode automatically resamples the stream to fit with the audio context if necessary.
- //
- // 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.
- //
- // Deprecated: as of v2.1. Use DecodeWithSampleRate instead.
- func Decode(context *audio.Context, src io.Reader) (*Stream, error) {
- return DecodeWithSampleRate(context.SampleRate(), src)
- }
|