Frozen5293's blog Frozen5293's blog
首页
  • 游戏开发
  • 博客相关
  • 技术问题
  • 分类
  • 标签
  • 归档
  • 友情链接
关于
GitHub (opens new window)

Frozen5293

刀剑钺戟摧狂浪,山河草木岁众生
首页
  • 游戏开发
  • 博客相关
  • 技术问题
  • 分类
  • 标签
  • 归档
  • 友情链接
关于
GitHub (opens new window)
  • 7

    • 如何在一个通道中播放多个音频
      • 更改通道中播放的声音
        • 并发处理
        frozen5293
        2023-08-15
        随笔
        目录

        7

        SDL2(Simple DirectMedia Layer 2)是一个跨平台的多媒体开发库,它提供了对音频、图形、输入等功能的封装。下面是SDL2音频部分的API使用方式的简要介绍,并给出一个简单的案例:

        # 如何在一个通道中播放多个音频

        在SDL2中的一个音频通道中播放多个音频可以使用混音(Mixing)功能来实现。SDL_mixer库提供了混音功能,可以将多个音频混合到一个通道中播放。下面是一个基本的示例:

        初始化SDL2和SDL_mixer:

        if (SDL_Init(SDL_INIT_AUDIO) < 0) {
            // 初始化失败,处理错误
        }
        if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
            // 初始化SDL_mixer失败,处理错误
        }
        
        1
        2
        3
        4
        5
        6

        加载音频数据:

        Mix_Chunk* sound1 = Mix_LoadWAV("sound1.wav");
        Mix_Chunk* sound2 = Mix_LoadWAV("sound2.wav");
        
        1
        2

        使用Mix_LoadWAV函数加载音频文件,并将返回的Mix_Chunk分配给不同的指针,以便后续使用。

        创建一个混音通道:

        int mixingChannel = Mix_GroupAvailable(1);
        if (mixingChannel == -1) {
            // 创建混音通道失败,处理错误
        }
        
        1
        2
        3
        4

        使用Mix_GroupAvailable函数创建一个混音通道。这将返回一个可用的混音通道编号,或者返回-1表示创建失败。

        设置混音通道属性:

        Mix_GroupChannel(mixingChannel, -1);
        Mix_Volume(mixingChannel, MIX_MAX_VOLUME);  // 设置音量
        
        1
        2

        使用Mix_GroupChannel函数将混音通道与所有通道相关联。然后,使用Mix_Volume函数设置混音通道的音量。

        播放音频:

        Mix_PlayChannel(mixingChannel, sound1, 0);
        Mix_PlayChannel(mixingChannel, sound2, 0);
        
        1
        2

        使用Mix_PlayChannel函数将音频混合到混音通道中播放。你可以多次调用Mix_PlayChannel来播放不同的音频。第一个参数是混音通道编号,第二个参数是要播放的音频,第三个参数是循环次数(0表示不循环)。

        清理和关闭SDL2和SDL_mixer:

        Mix_FreeChunk(sound1);
        Mix_FreeChunk(sound2);
        
        Mix_CloseAudio();
        SDL_Quit();
        
        1
        2
        3
        4
        5

        在程序结束时,确保释放加载的音频资源,并关闭SDL2和SDL_mixer。

        # 更改通道中播放的声音

        #include <SDL2/SDL.h>
        #include <SDL2/SDL_mixer.h>
        
        Mix_Chunk* sound1;
        Mix_Chunk* sound2;
        int channel;
        
        int main() {
            if (SDL_Init(SDL_INIT_AUDIO) < 0) {
                // 初始化失败,处理错误
                return -1;
            }
        
            if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
                // 初始化SDL_mixer失败,处理错误
                return -1;
            }
        
            sound1 = Mix_LoadWAV("sound1.wav");
            sound2 = Mix_LoadWAV("sound2.wav");
            channel = Mix_PlayChannel(-1, sound1, 0);
        
            if (channel == -1) {
                // 播放音频失败,处理错误
                return -1;
            }
        
            // 播放一段时间后更改通道中的声音
            SDL_Delay(5000);
            Mix_PlayChannel(channel, sound2, 0);
        
            while (Mix_Playing(channel) != 0) {
                // 等待当前音频播放完毕
                SDL_Delay(100);
            }
        
            Mix_FreeChunk(sound1);
            Mix_FreeChunk(sound2);
            Mix_CloseAudio();
            SDL_Quit();
        
            return 0;
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43

        在这个示例中,我们先加载两个不同的音频文件sound1.wav和sound2.wav。然后,我们使用Mix_PlayChannel函数将sound1播放到一个通道中,并将返回的通道编号存储在channel变量中。

        在经过一段时间后(在示例中是延迟5000毫秒),我们调用Mix_PlayChannel函数将通道中的音频更改为sound2。这样就会停止播放sound1并开始播放sound2。

        当更改通道中的音频时,之前的音频会立即停止,然后开始播放新的音频。

        # 并发处理

            锁的精确范围:在使用锁时,应该尽量缩小锁的范围,只在需要保护共享资源的关键代码段中获取锁。在获取锁之前和释放锁之后的代码应尽量简短,以减少锁的持有时间,从而提高并发能力。
            使用并发队列或消息传递
        
        1
        2

        当使用乐器来表达情绪时,以下是一些常见的对应关系,它们基于一般人对乐器音色的理解和经验,尽管这些对应并不是绝对的,而且在不同的文化和背景中可能存在差异。

        小提琴:悲伤、浪漫、温柔
        钢琴:优雅、安静、深情
        古典吉他:轻松、舒缓、温暖
        大提琴:庄重、深沉、宏伟
        竖琴:神秘、幻想、仙境
        长笛:清新、轻盈、欢快
        小号:鲜明、光明、欢乐
        萨克斯风:性感、浪漫、激情
        鼓:激烈、战斗、紧张
        管风琴:庄严、庄重、雄壮
        

        请记住,这只是一般人对乐器音色的一种理解,实际上乐器的情感表达是非常灵活和个人化的,取决于演奏者的技巧、音乐作品的要求以及听众的背景和情绪状态。

        在设计音效时,你可以参考这些对应关系,但也要根据具体情景和游戏的需求来选择乐器和音色。同时,通过控制乐器的演奏方式(如音量、速度、音域等),以及使用音效的变化和组合,可以更好地传达情感和营造游戏氛围。

        最重要的是,你可以根据你自己的直觉和创造力来实验和探索不同的音效组合,以找到最适合你游戏的表达方式。

        编辑 (opens new window)
        上次更新: 2024/04/16, 00:35:21
        最近更新
        01
        Rust序列化函数
        04-29
        02
        Rust错误处理
        04-29
        03
        1
        04-29
        更多文章>
        Theme by Vdoing | Copyright © 2019-2024 Frozen5293 | MIT License
        • 跟随系统
        • 浅色模式
        • 深色模式
        • 阅读模式