SDL2 音频选择输出 "channel"
SDL2 audio choose output "channel"
我正在尝试使用 nodejs 库 https://github.com/duobeiyun/node-sdl-speaker 在特定声卡的特定音频通道上播放声音,但我的问题并不特定于该库。这是一个 SDL 音频问题。
通过修改 src/SDLSpeaker.cpp,我可以 select 使用 SDL_OpenAudioDevice
而不是 SDL_OpenAudio
的声音设备。我将第 62 行替换为以下代码:
// Select second audio device
if (int errorCode = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(1, 0), 0, &wanted_spec, NULL, SDL_AUDIO_ALLOW_FORMAT_CHANGE) < 0) {
[…]
现在,我想强制仅向左输出声音。我认为我应该通过更改 fill_audio
来做到这一点,但我不知道该怎么做...:(
我找到了解决办法!
SDL 不适合我的需要,SDL_MIXER 是 !
我正在根据我编写的这段 C 代码编写一个节点插件:
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int continuer = 1;
SDL_Init(SDL_INIT_AUDIO);
Mix_Init(MIX_INIT_MP3);
int i, count = SDL_GetNumAudioDevices(0);
printf("-----------------------------------------\n");
printf("Available audio devices:\n");
for (i = 0; i < count; ++i)
{
printf(" - Audio device %d: %s\n", i, SDL_GetAudioDeviceName(i, 0));
}
printf("\n");
if (argc <= 2)
{
return EXIT_FAILURE;
}
char *deviceName = argv[1];
if (Mix_OpenAudioDevice(44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024,
deviceName, SDL_AUDIO_ALLOW_ANY_CHANGE) == -1)
{
printf("[SDL ERROR] :: %s\n\n", Mix_GetError());
return EXIT_FAILURE;
}
printf("Audio device \"%s\" opened with success\n", deviceName);
printf("-----------------------------------------\n\n");
int MAX_SOUNDS = argc - 3;
int currentSound = 0;
char **files; // = {"file1.wav", "ding.wav"};
files = (char **)malloc(MAX_SOUNDS * sizeof(char *));
for (int i = 0; i < MAX_SOUNDS; ++i)
{
files[i] = argv[3 + i];
}
Mix_AllocateChannels(1);
if (!Mix_SetPanning(0, argv[2][0] == '1' ? 255 : 0,
argv[2][0] == '1' ? 0 : 255))
{
printf("[SDL ERROR] :: Mix_SetPanning: %s\n", Mix_GetError());
}
Mix_Chunk *sounds[MAX_SOUNDS];
for (int i = 0; i < MAX_SOUNDS; ++i)
{
sounds[i] = Mix_LoadWAV(files[i]);
Mix_VolumeChunk(sounds[i], MIX_MAX_VOLUME);
}
Mix_PlayChannel(0, sounds[0], 0);
bool playing = true;
while (playing)
{
SDL_WaitEvent(NULL);
playing = Mix_Playing(0) != 0;
if (!playing && currentSound < MAX_SOUNDS)
{
++currentSound;
playing = true;
if (!Mix_SetPanning(0, argv[2][0] == '1' ? 255 : 0,
argv[2][0] == '1' ? 0 : 255))
{
printf("[SDL ERROR] :: Mix_SetPanning: %s\n", Mix_GetError());
}
Mix_PlayChannel(0, sounds[currentSound], 0);
}
printf("Channel 0: %s\r", playing ? "PLAYING" : "STOPPED");
}
for (int i = 0; i < MAX_SOUNDS; ++i)
{
Mix_FreeChunk(sounds[i]);
}
Mix_CloseAudio(); // Fermeture de l'API
printf("\n");
return EXIT_SUCCESS;
}
在 UNIX 上,要编译(必须在您的系统上安装 SDL2 和 SDL2_Mixer 开发依赖项):
$ cc test-sdl-mixer.cc `sdl2-config --cflags --libs` -lsdl2_mixer
编译后,该应用程序将在特定声卡的特定通道(仅左或右)上按顺序播放声音文件。
$ ./a.out "Built-in Output" 1 chime.wav advert.wav
它工作得很好,但在我写的节点模块中,我必须使用 child_process
fork()
才能在 2 个不同的频道或设备上播放 2 种声音,因为 SDL2 和 SDL2_Mixer 创建播放器/混音器的实例。
节点模块即将推出。
我正在尝试使用 nodejs 库 https://github.com/duobeiyun/node-sdl-speaker 在特定声卡的特定音频通道上播放声音,但我的问题并不特定于该库。这是一个 SDL 音频问题。
通过修改 src/SDLSpeaker.cpp,我可以 select 使用 SDL_OpenAudioDevice
而不是 SDL_OpenAudio
的声音设备。我将第 62 行替换为以下代码:
// Select second audio device
if (int errorCode = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(1, 0), 0, &wanted_spec, NULL, SDL_AUDIO_ALLOW_FORMAT_CHANGE) < 0) {
[…]
现在,我想强制仅向左输出声音。我认为我应该通过更改 fill_audio
来做到这一点,但我不知道该怎么做...:(
我找到了解决办法! SDL 不适合我的需要,SDL_MIXER 是 !
我正在根据我编写的这段 C 代码编写一个节点插件:
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int continuer = 1;
SDL_Init(SDL_INIT_AUDIO);
Mix_Init(MIX_INIT_MP3);
int i, count = SDL_GetNumAudioDevices(0);
printf("-----------------------------------------\n");
printf("Available audio devices:\n");
for (i = 0; i < count; ++i)
{
printf(" - Audio device %d: %s\n", i, SDL_GetAudioDeviceName(i, 0));
}
printf("\n");
if (argc <= 2)
{
return EXIT_FAILURE;
}
char *deviceName = argv[1];
if (Mix_OpenAudioDevice(44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024,
deviceName, SDL_AUDIO_ALLOW_ANY_CHANGE) == -1)
{
printf("[SDL ERROR] :: %s\n\n", Mix_GetError());
return EXIT_FAILURE;
}
printf("Audio device \"%s\" opened with success\n", deviceName);
printf("-----------------------------------------\n\n");
int MAX_SOUNDS = argc - 3;
int currentSound = 0;
char **files; // = {"file1.wav", "ding.wav"};
files = (char **)malloc(MAX_SOUNDS * sizeof(char *));
for (int i = 0; i < MAX_SOUNDS; ++i)
{
files[i] = argv[3 + i];
}
Mix_AllocateChannels(1);
if (!Mix_SetPanning(0, argv[2][0] == '1' ? 255 : 0,
argv[2][0] == '1' ? 0 : 255))
{
printf("[SDL ERROR] :: Mix_SetPanning: %s\n", Mix_GetError());
}
Mix_Chunk *sounds[MAX_SOUNDS];
for (int i = 0; i < MAX_SOUNDS; ++i)
{
sounds[i] = Mix_LoadWAV(files[i]);
Mix_VolumeChunk(sounds[i], MIX_MAX_VOLUME);
}
Mix_PlayChannel(0, sounds[0], 0);
bool playing = true;
while (playing)
{
SDL_WaitEvent(NULL);
playing = Mix_Playing(0) != 0;
if (!playing && currentSound < MAX_SOUNDS)
{
++currentSound;
playing = true;
if (!Mix_SetPanning(0, argv[2][0] == '1' ? 255 : 0,
argv[2][0] == '1' ? 0 : 255))
{
printf("[SDL ERROR] :: Mix_SetPanning: %s\n", Mix_GetError());
}
Mix_PlayChannel(0, sounds[currentSound], 0);
}
printf("Channel 0: %s\r", playing ? "PLAYING" : "STOPPED");
}
for (int i = 0; i < MAX_SOUNDS; ++i)
{
Mix_FreeChunk(sounds[i]);
}
Mix_CloseAudio(); // Fermeture de l'API
printf("\n");
return EXIT_SUCCESS;
}
在 UNIX 上,要编译(必须在您的系统上安装 SDL2 和 SDL2_Mixer 开发依赖项):
$ cc test-sdl-mixer.cc `sdl2-config --cflags --libs` -lsdl2_mixer
编译后,该应用程序将在特定声卡的特定通道(仅左或右)上按顺序播放声音文件。
$ ./a.out "Built-in Output" 1 chime.wav advert.wav
它工作得很好,但在我写的节点模块中,我必须使用 child_process
fork()
才能在 2 个不同的频道或设备上播放 2 种声音,因为 SDL2 和 SDL2_Mixer 创建播放器/混音器的实例。
节点模块即将推出。