Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NewContext occupies 5% of the CPU, even if no audio is played #229

Open
zwjjiaozhu opened this issue Dec 24, 2023 · 13 comments
Open

NewContext occupies 5% of the CPU, even if no audio is played #229

zwjjiaozhu opened this issue Dec 24, 2023 · 13 comments

Comments

@zwjjiaozhu
Copy link

os:macos 12.6

When the audio is not playing, I see that the idle wake-up thread is constantly increasing in the activity monitor software on the Mac
I don't know why it doesn't play audio and still takes up CPU to calculate
Is there any way to solve it? Thank you

image
@hajimehoshi
Copy link
Member

Could you give me a minimized code to reproduce this issue?

@zwjjiaozhu
Copy link
Author

Could you give me a minimized code to reproduce this issue?

thanks

package main

import (
	"github.com/ebitengine/oto/v3"
	"github.com/hajimehoshi/go-mp3"
	"os"
	"time"
)

func main() {
	file, _ := os.Open("test.mp3")
	defer file.Close()
	decoder, _ := mp3.NewDecoder(file)

	op := &oto.NewContextOptions{}

	// Usually 44100 or 48000. Other values might cause distortions in Oto
	op.SampleRate = 24100

	// Number of channels (aka locations) to play sounds from. Either 1 or 2.
	// 1 is mono sound, and 2 is stereo (most speakers are stereo).
	op.ChannelCount = 2

	// Format of the source. go-mp3's format is signed 16bit integers.
	op.Format = oto.FormatSignedInt16LE

	var otoContext *oto.Context
	var readyChan chan struct{}
	// 在newContext中会有5%的cpu
	otoContext, readyChan, _ = oto.NewContext(op)
	<-readyChan
	player := otoContext.NewPlayer(decoder)
	defer player.Close()
	player.Play()
	time.Sleep(2 * time.Second)
	player.Close()
	time.Sleep(200 * time.Second)
}

@hajimehoshi
Copy link
Member

I'm not sure the issue. Your program plays an MP3 file.

@Asday
Copy link

Asday commented Dec 28, 2023

You may need to share the MP3 file you're using.

@zwjjiaozhu
Copy link
Author

test.mp3.zip

You may need to share the MP3 file you're using.

@zwjjiaozhu
Copy link
Author

driver_darwin.go -> newContext -> loop(),

func (c *context) loop() {
	buf32 := make([]float32, c.oneBufferSizeInBytes/4)
	for {
		if !c.wait() {
			return
		}
		c.appendBuffer(buf32)
	}
}

I found that there was a constant loop here, and when I tried to print the variable buf32, I found that it kept printing [0,0,..., 0]. It should be using CPU calculation here.

@hajimehoshi
Copy link
Member

I don't quite understand.

I don't know why it doesn't play audio and still takes up CPU to calculate

But your program plays an audio...

@zwjjiaozhu
Copy link
Author

我不太明白。

不知道为什么不播放音频还占用CPU计算

但是你的程序播放音频......

After playing the audio, the CPU will still be used

@hajimehoshi
Copy link
Member

Even though there is no player, Oto tries to fill 0s to the underlying audio buffer, so this is expected.

@hajimehoshi
Copy link
Member

In order to optimize this, we might be able to pause the audio when there is no player, and resume when a new player comes. I am not sure I will do it.

@zwjjiaozhu
Copy link
Author

Thank you. So, how should I close this context after I finish playing the audio

@hajimehoshi
Copy link
Member

There is no way to close the context. You can call Suspend and Resume instead. https://pkg.go.dev/github.com/ebitengine/oto/v3#Context.Suspend

@zwjjiaozhu
Copy link
Author

ok, Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants