我试图在C#中改变声音字节[]的音量。我正在用FFMPEG读取声音文件,并且想要动态改变音量。我找到了一些例子,但我不理解它们。
public void SendAudio(string pathOrUrl)
{
cancelVid = false;
isPlaying = true;
mProcess = Process.Start(new ProcessStartInfo
{ // FFmpeg requireqs us to spawn a process and hook into its stdout, so we will create a Process
FileName = "ffmpeg",
Arguments = "-i " + (char)34 + pathOrUrl + (char)34 + // Here we provide a list of arguments to feed into FFmpeg. -i means the location of the file/URL it will read from
" -f s16le -ar 48000 -ac 2 pipe:1", // Next, we tell it to output 16-bit 48000Hz PCM, over 2 channels, to stdout.
UseShellExecute = false,
RedirectStandardOutput = true, // Capture the stdout of the process
Verb = "runas"
});
while (!isRunning(mProcess)) { Task.Delay(1000); }
int blockSize = 3840; // The size of bytes to read per frame; 1920 for mono
byte[] buffer = new byte[blockSize];
byte[] gainBuffer = new byte[blockSize];
int byteCount;
while (true && !cancelVid) // Loop forever, so data will always be read
{
byteCount = mProcess.StandardOutput.BaseStream // Access the underlying MemoryStream from the stdout of FFmpeg
.Read(buffer, 0, blockSize); // Read stdout into the buffer
if (byteCount == 0) // FFmpeg did not output anything
break; // Break out of the while(true) loop, since there was nothing to read.
if (cancelVid)
break;
disAudioClient.Send(buffer, 0, byteCount); // Send our data to Discord
}
disAudioClient.Wait(); // Wait for the Voice Client to finish sending data, as ffMPEG may have already finished buffering out a song, and it is unsafe to return now.
isPlaying = false;
Console.Clear();
Console.WriteLine("Done Playing!");
答案 0 :(得分:0)
你的问题不是很好。想象一下,你正在谈论一个图像并询问"如何减少图像字节中的红色数量[]?"。答案是你必须解码相应位深度的byte []和RGB元组,修改R值然后转换回byte []。这里也是一样的。您将byte []转换为适当位深度的样本,重新缩放,然后转换回byte []。
在你的情况下,每个样本有16位,所以你需要将每对连续的字节连接成一个短的,缩放它,然后再分开。
从您读取字节[]的位置开始:
for (int i = 0 ; i < blockSize/2 ; ++i)
{
// convert to 16-bit
short sample = (short)((buffer[i*2+1] << 8) | buffer[i*2])
// scale
const double gain = 0.5; // value between 0 and 1.0
sample = (short)(sample * gain + 0.5);
// back to byte[]
buffer[i*2+1] = (byte)(sample >> 8);
buffer[i*2] = (byte)(sample & 0xff);
}