提问人:Carl Younger 提问时间:10/4/2023 最后编辑:Carl Younger 更新时间:10/5/2023 访问量:199
如何使用 raylib 播放原始音频
How to play raw audio with raylib
问:
我正在尝试弄清楚 raylib API,甚至无法生成白噪声。我听到一阵短暂的噪音(可能是 100 毫秒),但随后它就安静了。AudioStream
目前只有一个使用 raylib 生成音频的官方示例(还有一些可以播放的示例),我找不到有关 API 的任何其他文档。AudioStream
我编写了一个最小的 C 程序,它应该在屏幕上显示静态文本的同时简单地输出白噪声。它“工作”了几分之一秒,然后就没有声音了。raylib 也没有错误消息(一切都报告为成功)。
我使用的是 32 位整数样本,单声道,频率为 48KHz。我更喜欢使用浮点数,但官方示例使用 ints (),所以我现在使用它。short
代码如下:
/* ====================================================================
WARNING: LOWER YOUR SPEAKERS - THEY WILL POP WHEN THIS PROGRAM EXECUTES
=======================================================================
*/
#include "raylib.h"
#include <stdlib.h> // required for `rand` and `RAND_MAX`
#define U32_MAX 4294967296
#define U31_MAX 2147483648
int randomSample() {
/* This helper returns a random, signed 32-bit sample. */
double randomFraction = rand() / (double)(RAND_MAX);
return randomFraction * U32_MAX - U31_MAX;
}
void generateSamples(void * buffer, unsigned int frames) {
/* This audio callback fills a mono buffer with white noise. */
int * samples = (int *)buffer;
for (unsigned int i = 0; i < frames; i++) samples[i] = randomSample();
}
int main(void) {
/* This is a textbook raylib main function. It sets up an audio
callback, then loops while the window stays open, before tearing
down the window, audio device, stream etc. */
InitWindow(800, 480, "playlib");
InitAudioDevice();
AudioStream stream = LoadAudioStream(48000, 32, 1);
SetAudioStreamBufferSizeDefault(1024);
SetAudioStreamVolume(stream, 1.0f);
SetAudioStreamCallback(stream, generateSamples);
PlayAudioStream(stream);
SetTargetFPS(60);
while (!WindowShouldClose()) { // loop just redraws the same text
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("MUSIC SHOULD BE PLAYING!", 245, 150, 20, LIGHTGRAY);
EndDrawing();
}
UnloadAudioStream(stream);
CloseAudioDevice();
CloseWindow();
return 0;
}
在LLDB中,我能够确定正在(重复)调用回调,正在生成样本,并写入缓冲区。然而,我听到的只是应用程序打开时发出的短促的噪音。文本呈现没有问题。
我尝试将缓冲区大小更改为 256 和 4096 之间的 2 的明显幂,但没有效果。
另一件事:当程序启动时,我笔记本电脑上的所有其他音频都会静音,然后在我关闭程序时自行取消静音。这就像 raylib 不能共享输出设备,所以它只是独占接管它。我不确定这是否就是 raylib 的工作方式,但这似乎是错误的。
这是在最新的 M1 Mac 上。
答:
0赞
twelfth
10/5/2023
#1
根据评论,我不太确定您所说的放置在动画循环中的意思。这似乎不是示例中发生的情况。UpdateMusicStream(music)
尽管如此,下面是一个最小的可重现示例,只要打开它,它就会播放音频文件。此外,如果您想要此功能,它会在按下时播放声音。Window
MOUSE_BUTTON_LEFT
#include "raylib.h"
int main(void)
{
Sound sound;
Music music;
int width = 800;
int height = 450;
InitWindow(width, height, "title");
InitAudioDevice();
sound = LoadSound("sound.wav");
music = LoadMusicStream("music.mp3");
PlayMusicStream(music);
while (!WindowShouldClose())
{
UpdateMusicStream(music);
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{
PlaySound(sound);
}
BeginDrawing();
ClearBackground(GRAY);
DrawText("MUSIC SHOULD BE PLAYING!", width / 2, height / 2, 20, LIGHTGRAY);
EndDrawing();
}
StopMusicStream(music);
CloseAudioDevice();
CloseWindow();
return 0;
}
评论
1赞
Carl Younger
10/5/2023
while 循环迭代(和调用)的频率是多少?我假设它每帧动画运行一次,例如等。UpdateMusicStream
BeginDrawing
1赞
Carl Younger
10/5/2023
我很欣赏这个建议,并会尝试调整它,但我真的很想在运行时生成样本,然后使用 .本示例播放现有文件。谢谢,但这不会输出白噪声。AudioStream
评论
for (unsigned int i; i < frames; i++) samples[i] = randomSample();
未定义的行为。 未初始化。此外,您在创建 时将样本大小指定为 32 位,但随后您用只有 16 位的值填充缓冲区。i
AudioStream
LoadAudioStream(48000, 32, 1);
short
short
int
unsigned int i = 0
Refill audio stream if required
IsAudioStreamProcessed(stream)
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE)
UpdateAudioStream