ebiten 学习(10)-loop.go

本文详细分析了Ebiten库中用于创建无限循环音频的`loop`包,包括`InfiniteLoop`结构及其`NewInfiniteLoopWithIntro`方法。通过实例展示了如何从解码的Ogg文件创建无限循环流,并使用Ebiten的音频上下文播放。代码示例中,音频会在5秒到15秒之间无限循环播放。
摘要由CSDN通过智能技术生成

2021SC@SDUSC


一、前言

1.说明

audio 说明文档地址

audio package - github.com/hajimehoshi/ebiten/v2/audio - pkg.go.dev

本文中所有截图和代码均来自说明文档或 ebiten 源文件

笔者负责 audio 音频相关的代码分析

2.梗概

阅读 loop.go 的代码,分析大概的逻辑和功能。


二、loop

1.主要方法

InfiniteLoop 表示一个永不结束的循环流。

在这里插入图片描述

NewInfiniteLop 根据源流创建一个新的无限循环流,长度以字节为单位。

在这里插入图片描述

NewInfiniteLopWithIntro 创建一个新的带有 前缀 部分的无限循环流。
NewInfiniteLopWithIntro 接受源流 src、introLength(字节)和loopLength(字节)。

在这里插入图片描述

返回长度,前缀长度加循环长度

在这里插入图片描述

确认流的位置无误。

在这里插入图片描述

Read 方法是 ReadSeekCloser 中 Read 方法的实现。

在这里插入图片描述

Seek 同上,也是 Seek 的实现。

在这里插入图片描述

2.用例

详见之前的博客“无限循环播放器”。

使用解码的字节创建一个无限循环流。
s 是一个 ReadCloser 流,也是一个 Seeker 流。

在这里插入图片描述
我自己写的例子

//go:build linux || darwin || windows
// +build linux darwin windows

package main

import (
	"bytes"
	"fmt"
	"log"
	"time"

	//myogg "./res"
	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/audio"
	"github.com/hajimehoshi/ebiten/v2/audio/vorbis"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)

const (
	screenWidth  = 640
	screenHeight = 480
	sampleRate   = 22050

	introLengthInSecond = 5
	loopLengthInSecond  = 10
)

type Game struct {
	player       *audio.Player
	audioContext *audio.Context
}

func (g *Game) Update() error {
	if g.player != nil {
		return nil
	}

	if g.audioContext == nil {
		g.audioContext = audio.NewContext(sampleRate)
	}

	// 解码ogg
	oggS, err := vorbis.Decode(g.audioContext, bytes.NewReader(TJF))
	if err != nil {
		return err
	}

	// 套一层无限循环的壳
	s := audio.NewInfiniteLoopWithIntro(oggS, introLengthInSecond*4*sampleRate, loopLengthInSecond*4*sampleRate)

	g.player, err = g.audioContext.NewPlayer(s)
	if err != nil {
		return err
	}

	// 播放
	g.player.Play()
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	pos := g.player.Current()
	if pos > 5*time.Second {
		pos = (g.player.Current()-5*time.Second)%(10*time.Second) + 5*time.Second
	}
	msg := fmt.Sprintf(`TPS: %0.2f
Mr.tang jiafeng's best wish

intro:   0[s] - %[2]d[s]
loop:    %[2]d[s] - %[3]d[s]
current: %0.2[4]f[s]`, ebiten.CurrentTPS(), introLengthInSecond, introLengthInSecond+loopLengthInSecond, float64(pos)/float64(time.Second))
	ebitenutil.DebugPrint(screen, msg)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return screenWidth, screenHeight
}

func main() {
	ebiten.SetWindowSize(screenWidth, screenHeight)
	ebiten.SetWindowTitle("MyOggDemo1")
	if err := ebiten.RunGame(&Game{}); err != nil {
		log.Fatal(err)
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值