示例#1
0
func ExampleMonitor() {
	const (
		frequency    = 44100
		format       = openal.FormatStereo16
		captureSize  = 512
		buffersCount = 10
	)
	mic := openal.CaptureOpenDevice("", frequency, format, frequency*2)
	mic.CaptureStart()
	defer mic.CloseDevice()

	device := openal.OpenDevice("")
	defer device.CloseDevice()

	context := device.CreateContext()
	context.Activate()
	defer context.Destroy()

	source := openal.NewSource()
	source.SetLooping(false)
	defer source.Stop()

	buffers := openal.NewBuffers(buffersCount)
	samples := make([]byte, captureSize*format.SampleSize())

	start := time.Now()
	for time.Since(start) < time.Second { // play for 1 second
		if err := openal.Err(); err != nil {
			fmt.Println("error:", err)
			return
		}
		// Get any free buffers
		if prcessed := source.BuffersProcessed(); prcessed > 0 {
			buffersNew := make(openal.Buffers, prcessed)
			source.UnqueueBuffers(buffersNew)
			buffers = append(buffers, buffersNew...)
		}
		if len(buffers) == 0 {
			continue
		}

		if mic.CapturedSamples() >= captureSize {
			mic.CaptureTo(samples)
			buffer := buffers[len(buffers)-1]
			buffers = buffers[:len(buffers)-1]
			buffer.SetData(format, samples, frequency)
			source.QueueBuffer(buffer)

			// If we have enough buffers, start playing
			if source.State() != openal.Playing {
				if source.BuffersQueued() > 2 {
					source.Play()
				}
			}
		}
	}
	fmt.Println(source.State())
	// Output: Playing
}
示例#2
0
func NewPlayer(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{},
		sampleRate: sampleRate,
		alFormat:   alFormat(channelNum, bytesPerSample),
	}
	runtime.SetFinalizer(p, (*Player).Close)

	bs := openal.NewBuffers(maxBufferNum)
	const bufferSize = 1024
	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.alBuffers = append(p.alBuffers, b)
	}
	p.alSource.Play()
	return p, nil
}
示例#3
0
func initialize() {
	// Creating OpenAL device must be done after initializing UI. I'm not sure the reason.
	ch := make(chan struct{})
	go func() {
		runtime.LockOSThread()

		device := openal.OpenDevice("")
		context := device.CreateContext()
		context.Activate()

		if alErr := openal.GetError(); alErr != 0 {
			log.Printf("OpenAL initialize error: %d", alErr)
			close(ch)
			// Graceful ending: Audio is not available on Travis CI.
			return
		}

		audioEnabled = true
		sources := openal.NewSources(MaxChannel)
		close(ch)

		const bufferSize = 2048
		emptyBytes := make([]byte, bufferSize)

		for _, source := range sources {
			// 3 is the least number?
			// http://stackoverflow.com/questions/14932004/play-sound-with-openalstream
			const bufferNum = 4
			buffers := openal.NewBuffers(bufferNum)
			for _, buffer := range buffers {
				buffer.SetData(openal.FormatStereo16, emptyBytes, SampleRate)
				source.QueueBuffer(buffer)
			}
			source.Play()
			if alErr := openal.GetError(); alErr != 0 {
				panic(fmt.Sprintf("OpenAL error: %d", alErr))
			}
		}

		for {
			oneProcessed := false
			for ch, source := range sources {
				processed := source.BuffersProcessed()
				if processed == 0 {
					continue
				}

				oneProcessed = true
				buffers := make([]openal.Buffer, processed)
				source.UnqueueBuffers(buffers)
				for _, buffer := range buffers {
					b := make([]byte, bufferSize)
					copy(b, loadChannelBuffer(ch, bufferSize))
					buffer.SetData(openal.FormatStereo16, b, SampleRate)
					source.QueueBuffer(buffer)
				}
				if source.State() == openal.Stopped {
					source.Rewind()
					source.Play()
				}
			}
			if !oneProcessed {
				time.Sleep(1 * time.Millisecond)
			}
		}
	}()
	<-ch
}