Esempio n. 1
0
// Forward 'AudioData' objects from 'audio.data' to 'audio.playback'
func forwarderLoop(evtLoop *spectrum.EventLoop, audio *SDLAudio) {
	audioDataChannel := audio.data
	playback_closed := false

	shutdown.Add(1)
	for {
		select {
		case <-evtLoop.Pause:
			// Remove all enqueued AudioData objects
		loop:
			for {
				select {
				case <-audio.playback:
				default:
					break loop
				}
			}

			audio.mutex.Lock()
			{
				if !audio.sdlAudioUnpaused {
					// Unpause SDL Audio. This is needed in order to avoid
					// a potential deadlock on 'sdl_audio.SendAudio_int16()'.
					// (If audio is paused, 'sdl_audio.SendAudio_int16()' waits indefinitely.)
					sdl_audio.PauseAudio(false)
					audio.sdlAudioUnpaused = true
				}
			}
			audio.mutex.Unlock()

			close(audio.playback)
			playback_closed = true

			<-audio.playbackLoopFinished

			sdl_audio.CloseAudio()

			audio.mutex.Lock()
			forwarderLoopFinished := audio.forwarderLoopFinished
			audio.mutex.Unlock()
			if forwarderLoopFinished != nil {
				forwarderLoopFinished <- 0
			}

			evtLoop.Pause <- 0

		case <-evtLoop.Terminate:
			// Terminate this Go routine
			if evtLoop.App().Verbose {
				evtLoop.App().PrintfMsg("audio forwarder loop: exit")
			}
			evtLoop.Terminate <- 0
			shutdown.Done()
			return

		case audioData := <-audioDataChannel:
			if audioData != nil {
				if !playback_closed {
					audio.bufferAdd()
					audio.playback <- audioData
				}
			} else {
				// Prevent any future sends via the 'audio.data' channel
				close(audio.data)

				// Replace 'audioDataChannel' with nil,
				// so that future executions of the 'select' statement ignore the "<-audioDataChannel" case
				audioDataChannel = nil

				// Go to the '<-evtLoop.Pause' case
				done := evtLoop.Delete()
				go func() { <-done }()
			}
		}
	}
}
Esempio n. 2
0
func (a *Audio) Close() {
	fmt.Println("Closing!")
	sdl_audio.PauseAudio(true)
	sdl_audio.CloseAudio()
}
Esempio n. 3
0
func (audio *SDLAudio) Close() {
	sdl_audio.PauseAudio(true)
	sdl_audio.CloseAudio()
}