示例#1
0
// Called when the number of buffered 'AudioData' objects increases by 1
func (audio *SDLAudio) bufferAdd() {
	audio.mutex.Lock()
	{
		audio.bufSize++

		// Unpause SDL audio if we have BUFSIZE_IDEAL 'AudioData' objects
		if !audio.sdlAudioUnpaused && (audio.bufSize == BUFSIZE_IDEAL) {
			sdl_audio.PauseAudio(false)
			audio.sdlAudioUnpaused = true
		}
	}
	audio.mutex.Unlock()
}
示例#2
0
func NewAudio() *Audio {
	as = sdl_audio.AudioSpec{
		Freq:        44100,
		Format:      sdl_audio.AUDIO_S16SYS,
		Channels:    1,
		Out_Silence: 0,
		Samples:     uint16(SampleSize),
		Out_Size:    0,
	}

	if sdl_audio.OpenAudio(&as, nil) < 0 {
		log.Fatal(sdl.GetError())
	}

	sdl_audio.PauseAudio(false)

	return &Audio{
		samples: make([]int16, SampleSize),
	}
}
示例#3
0
func (a *Audio) Run() {
	as := sdl_audio.AudioSpec{
		Freq:        44100,
		Format:      sdl_audio.AUDIO_S16SYS,
		Channels:    1,
		Out_Silence: 0,
		Samples:     uint16(SampleSize),
		Out_Size:    0,
	}

	if sdl_audio.OpenAudio(&as, nil) < 0 {
		log.Fatal(sdl.GetError())
	}

	sdl_audio.PauseAudio(false)

	for {
		select {
		case s := <-a.sample:
			a.AppendSample(s)
		}
	}
}
示例#4
0
func NewAudio(frequency int, sampleSize int) (audio *SDLAudio, err error) {
	spec := sdl_audio.AudioSpec{
		Freq:        frequency,
		Format:      sdl_audio.AUDIO_S16SYS,
		Channels:    1,
		Out_Silence: 0,
		Samples:     uint16(sampleSize),
		Out_Size:    0,
	}

	if sdl_audio.OpenAudio(&spec, nil) < 0 {
		err = errors.New(sdl.GetError())
		return
	}

	sdl_audio.PauseAudio(false)

	audio = &SDLAudio{
		samples: make([]int16, sampleSize),
		input:   make(chan int16),
	}

	return
}
示例#5
0
func (a *Audio) Close() {
	fmt.Println("Closing!")
	sdl_audio.PauseAudio(true)
	sdl_audio.CloseAudio()
}
示例#6
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 }()
			}
		}
	}
}
示例#7
0
func (audio *SDLAudio) Close() {
	sdl_audio.PauseAudio(true)
	sdl_audio.CloseAudio()
}
示例#8
0
func (audio *SDLAudio) TogglePaused() {
	audio.paused = !audio.paused
	sdl_audio.PauseAudio(audio.paused)
}