<commit_before>// Copyright 2015 <NAME>
//
// 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.

// +build !js,!windows

package driver

import (
	"fmt"
	"io"
	"runtime"

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

// As x/mobile/exp/audio/al is broken on Mac OS X (https://github.com/golang/go/issues/15075),
// let's use github.com/hajimehoshi/go-openal instead.

const (
	maxBufferNum = 8
)

type Player struct {
	alDevice   *openal.Device
	alSource   openal.Source
	alBuffers  []openal.Buffer
	source     io.Reader
	sampleRate int
	isClosed   bool
	alFormat   openal.Format
}

func alFormat(channelNum, bytesPerSample int) openal.Format {
	switch {
	case channelNum == 1 && bytesPerSample == 1:
		return openal.FormatMono8
	case channelNum == 1 && bytesPerSample == 2:
		return openal.FormatMono16
	case channelNum == 2 && bytesPerSample == 1:
		return openal.FormatStereo8
	case channelNum == 2 && bytesPerSample == 2:
		return openal.FormatStereo16
	}
	panic(fmt.Sprintf("driver: invalid channel num (%d) or bytes per sample (%d)", channelNum, bytesPerSample))
}

func NewPlayer(src io.Reader, sampleRate, channelNum, bytesPerSample int) (*Player, error) {
	d := openal.OpenDevice("")
	if d == nil {
		return nil, fmt.Errorf("driver: OpenDevice must not return nil")
	}
	c := d.CreateContext()
	if c == nil {
		return nil, fmt.Errorf("driver: CreateContext must not return nil")
	}
	// Don't check openal.Err until making the current context is done.
	// Linux might fail this check even though it succeeds (#204).
	c.Activate()
	if err := openal.Err(); err != nil {
		return nil, fmt.Errorf("driver: Activate: %v", err)
	}
	s := openal.NewSource()
	if err := openal.Err(); err != nil {
		return nil, fmt.Errorf("driver: NewSource: %v", err)
	}
	p := &Player{
		alDevice:   d,
		alSource:   s,
		alBuffers:  []openal.Buffer{},
		source:     src,
		sampleRate: sampleRate,
		alFormat:   alFormat(channelNum, bytesPerSample),
	}
	runtime.SetFinalizer(p, (*Player).Close)

	bs := openal.NewBuffers(maxBufferNum)
	emptyBytes := make([]byte, bufferSize)
	for _, b := range bs {
		// Note that the third argument of only the first buffer is used.
		b.SetData(p.alFormat, emptyBytes, int32(p.sampleRate))
		p.alSource.QueueBuffer(b)
	}
	p.alSource.Play()
	return p, nil
}

const (
	bufferSize = 1024
)

var (
	tmpBuffer    = make([]byte, bufferSize)
	tmpAlBuffers = make([]openal.Buffer, maxBufferNum)
)

func (p *Player) Proceed() error {
	if err := openal.Err(); err != nil {
		return fmt.Errorf("driver: starting Proceed: %v", err)
	}
	processedNum := p.alSource.BuffersProcessed()
	if 0 < processedNum {
		bufs := tmpAlBuffers[:processedNum]
		p.alSource.UnqueueBuffers(bufs)
		if err := openal.Err(); err != nil {
			return fmt.Errorf("driver: UnqueueBuffers: %v", err)
		}
		p.alBuffers = append(p.alBuffers, bufs...)
	}

	if 0 < len(p.alBuffers) {
		n, err := p.source.Read(tmpBuffer)
		if 0 < n {
			buf := p.alBuffers[0]
			p.alBuffers = p.alBuffers[1:]
			buf.SetData(p.alFormat, tmpBuffer[:n], int32(p.sampleRate))
			p.alSource.QueueBuffer(buf)
			if err := openal.Err(); err != nil {
				return fmt.Errorf("driver: QueueBuffer: %v", err)
			}
		}
		if err != nil {
			return err
		}
	}

	if p.alSource.State() == openal.Stopped || p.alSource.State() == openal.Initial {
		p.alSource.Rewind()
		p.alSource.Play()
		if err := openal.Err(); err != nil {
			return fmt.Errorf("driver: Rwind or Play: %v", err)
		}
	}

	return nil
}

func (p *Player) Close() error {
	if err := openal.Err(); err != nil {
		return fmt.Errorf("driver: starting Close: %v", err)
	}
	if p.isClosed {
		return nil
	}
	var bs []openal.Buffer
	p.alSource.Rewind()
	p.alSource.Play()
	if n := p.alSource.BuffersQueued(); 0 < n {
		bs = make([]openal.Buffer, n)
		p.alSource.UnqueueBuffers(bs)
		p.alBuffers = append(p.alBuffers, bs...)
	}
	p.alDevice.CloseDevice()
	p.isClosed = true
	if err := openal.Err(); err != nil {
		return fmt.Errorf("driver: CloseDevice: %v", err)
	}
	runtime.SetFinalizer(p, nil)
	return nil
}
<commit_msg>audio: Misspelling<commit_after>// Copyright 2015 <NAME>
//
// 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.

// +build !js,!windows

package driver

import (
	"fmt"
	"io"
	"runtime"

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

// As x/mobile/exp/audio/al is broken on Mac OS X (https://github.com/golang/go/issues/15075),
// let's use github.com/hajimehoshi/go-openal instead.

const (
	maxBufferNum = 8
)

type Player struct {
	alDevice   *openal.Device
	alSource   openal.Source
	alBuffers  []openal.Buffer
	source     io.Reader
	sampleRate int
	isClosed   bool
	alFormat   openal.Format
}

func alFormat(channelNum, bytesPerSample int) openal.Format {
	switch {
	case channelNum == 1 && bytesPerSample == 1:
		return openal.FormatMono8
	case channelNum == 1 && bytesPerSample == 2:
		return openal.FormatMono16
	case channelNum == 2 && bytesPerSample == 1:
		return openal.FormatStereo8
	case channelNum == 2 && bytesPerSample == 2:
		return openal.FormatStereo16
	}
	panic(fmt.Sprintf("driver: invalid channel num (%d) or bytes per sample (%d)", channelNum, bytesPerSample))
}

func NewPlayer(src io.Reader, sampleRate, channelNum, bytesPerSample int) (*Player, error) {
	d := openal.OpenDevice("")
	if d == nil {
		return nil, fmt.Errorf("driver: OpenDevice must not return nil")
	}
	c := d.CreateContext()
	if c == nil {
		return nil, fmt.Errorf("driver: CreateContext must not return nil")
	}
	// Don't check openal.Err until making the current context is done.
	// Linux might fail this check even though it succeeds (#204).
	c.Activate()
	if err := openal.Err(); err != nil {
		return nil, fmt.Errorf("driver: Activate: %v", err)
	}
	s := openal.NewSource()
	if err := openal.Err(); err != nil {
		return nil, fmt.Errorf("driver: NewSource: %v", err)
	}
	p := &Player{
		alDevice:   d,
		alSource:   s,
		alBuffers:  []openal.Buffer{},
		source:     src,
		sampleRate: sampleRate,
		alFormat:   alFormat(channelNum, bytesPerSample),
	}
	runtime.SetFinalizer(p, (*Player).Close)

	bs := openal.NewBuffers(maxBufferNum)
	emptyBytes := make([]byte, bufferSize)
	for _, b := range bs {
		// Note that the third argument of only the first buffer is used.
		b.SetData(p.alFormat, emptyBytes, int32(p.sampleRate))
		p.alSource.QueueBuffer(b)
	}
	p.alSource.Play()
	return p, nil
}

const (
	bufferSize = 1024
)

var (
	tmpBuffer    = make([]byte, bufferSize)
	tmpAlBuffers = make([]openal.Buffer, maxBufferNum)
)

func (p *Player) Proceed() error {
	if err := openal.Err(); err != nil {
		return fmt.Errorf("driver: starting Proceed: %v", err)
	}
	processedNum := p.alSource.BuffersProcessed()
	if 0 < processedNum {
		bufs := tmpAlBuffers[:processedNum]
		p.alSource.UnqueueBuffers(bufs)
		if err := openal.Err(); err != nil {
			return fmt.Errorf("driver: UnqueueBuffers: %v", err)
		}
		p.alBuffers = append(p.alBuffers, bufs...)
	}

	if 0 < len(p.alBuffers) {
		n, err := p.source.Read(tmpBuffer)
		if 0 < n {
			buf := p.alBuffers[0]
			p.alBuffers = p.alBuffers[1:]
			buf.SetData(p.alFormat, tmpBuffer[:n], int32(p.sampleRate))
			p.alSource.QueueBuffer(buf)
			if err := openal.Err(); err != nil {
				return fmt.Errorf("driver: QueueBuffer: %v", err)
			}
		}
		if err != nil {
			return err
		}
	}

	if p.alSource.State() == openal.Stopped || p.alSource.State() == openal.Initial {
		p.alSource.Rewind()
		p.alSource.Play()
		if err := openal.Err(); err != nil {
			return fmt.Errorf("driver: Rewind or Play: %v", err)
		}
	}

	return nil
}

func (p *Player) Close() error {
	if err := openal.Err(); err != nil {
		return fmt.Errorf("driver: starting Close: %v", err)
	}
	if p.isClosed {
		return nil
	}
	var bs []openal.Buffer
	p.alSource.Rewind()
	p.alSource.Play()
	if n := p.alSource.BuffersQueued(); 0 < n {
		bs = make([]openal.Buffer, n)
		p.alSource.UnqueueBuffers(bs)
		p.alBuffers = append(p.alBuffers, bs...)
	}
	p.alDevice.CloseDevice()
	p.isClosed = true
	if err := openal.Err(); err != nil {
		return fmt.Errorf("driver: CloseDevice: %v", err)
	}
	runtime.SetFinalizer(p, nil)
	return nil
}

{'fraction_non_alphanumeric': 0.14293610435551626, 'fraction_numerical': 0.009949148795047534, 'mean_word_length': 3.6064154786150713, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '812589', 'n_tokens_mistral': 3416, 'n_tokens_neox': 3184, 'n_words': 901}