gpt4 book ai didi

c# - 如何将 int16 声音样本数组转换为字节数组以在 MonoGame/XNA 中使用

转载 作者:太空宇宙 更新时间:2023-11-03 10:24:56 26 4
gpt4 key购买 nike

我正在用 C#/MonoGame 编写一个 libretro 前端,我设法得到了一个粗糙的(但可以工作的)视频 block ,但现在我正在努力处理声音。

来自 API:

/* Renders multiple audio frames in one go.
*
* One frame is defined as a sample of left and right channels, interleaved.
* I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames.
* Only one of the audio callbacks must ever be used.
*/
typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data,
size_t frames);

因此,样本是有符号的 16 位整数。我正在尝试像这样使用 Stream 中的 SoundEffect:

        int size = SoundEffect.GetSampleSizeInBytes(TimeSpan.FromMilliseconds((float)1000/(int)_libretro.GetAVInfo().timing.fps), (int)_libretro.GetAVInfo().timing.sample_rate, AudioChannels.Mono);           
data = _libretro.GetSoundBuffer().data;

byte[] buffer = new byte[size];
for (int i = 0; i < size -1 ; i+=2)
{
Int16 chunk = Marshal.ReadInt16(data);

byte b1 = (byte)(chunk);
byte b2 = (byte)(chunk >> 8);
buffer[i+1] = b1;
buffer[i] = b2;

//move ahead 4 bytes skipping the second sound channel for now
data = data + (sizeof(byte)*4);
}

SoundEffect sound_left = new SoundEffect(buffer, (int)_libretro.GetAVInfo().timing.sample_rate, AudioChannels.Mono);
sound_left.Play();

我听到了声音,声音模式清晰可辨,但它是乱码,您是否立即发现我的实现有任何问题?

最佳答案

此方法会将示例数据转换为字节数组。它适用于任何 channel 数(在单声道和立体声上测试)。

    public static byte[] GetSamplesWaveData(float[] samples, int samplesCount)
{
var pcm = new byte[samplesCount * 2];
int sampleIndex = 0,
pcmIndex = 0;

while (sampleIndex < samplesCount)
{
var outsample = (short)(samples[sampleIndex] * short.MaxValue);
pcm[pcmIndex] = (byte)(outsample & 0xff);
pcm[pcmIndex + 1] = (byte)((outsample >> 8) & 0xff);

sampleIndex++;
pcmIndex += 2;
}

return pcm;
}

请注意,float[] 样本 值应在 [-1;1] 范围内。

关于c# - 如何将 int16 声音样本数组转换为字节数组以在 MonoGame/XNA 中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31957211/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com