Ich verwende C# in Universal Windows App, um einen Watson Speech-to-Text-Dienst zu schreiben. Für den Moment, anstatt den Watson-Dienst zu verwenden, schreibe ich in die Datei und lese es dann in Audacity, um zu bestätigen, dass es im richtigen Format ist, da der Watson-Dienst die richtigen Antworten nicht an mich zurücksendet, und das folgende erklärt warum.Audiokodierung Konvertierungsprobleme mit PCM 32-Bit-PCM 16-Bit
Aus irgendeinem Grund, wenn ich 16-Bit-PCM-Codierungseigenschaften erstellen und Puffer lesen, kann ich nur Daten als 32-Bit-PCM lesen, und es funktioniert gut, aber wenn ich es in 16-Bit-PCM lesen ist in Zeitlupe, und die ganze Sprache ist im Grunde korrupt.
Ich weiß nicht wirklich, was genau getan werden muss, von 32-Bit auf 16-Bit zu konvertieren, aber hier ist es, was ich in meiner C# Anwendung habe:
//Creating PCM Encoding properties
var pcmEncoding = AudioEncodingProperties.CreatePcm(16000, 1, 16);
var result = await AudioGraph.CreateAsync(
new AudioGraphSettings(AudioRenderCategory.Speech)
{
DesiredRenderDeviceAudioProcessing = AudioProcessing.Raw,
AudioRenderCategory = AudioRenderCategory.Speech,
EncodingProperties = pcmEncoding
}
);
graph = result.Graph;
//Initialize microphone
var microphone = await DeviceInformation.CreateFromIdAsync(MediaDevice.GetDefaultAudioCaptureId(AudioDeviceRole.Default));
var micInputResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Speech, pcmEncoding, microphone);
//Create frame output node
frameOutputNode = graph.CreateFrameOutputNode(pcmEncoding);
//Callback function to fire when buffer is filled with data
graph.QuantumProcessed += (s, a) => ProcessFrameOutput(frameOutputNode.GetFrame());
frameOutputNode.Start();
//Make the microphone write into the frame node
micInputResult.DeviceInputNode.AddOutgoingConnection(frameOutputNode);
micInputResult.DeviceInputNode.Start();
graph.Start();
Initialisierungsschritt auf dies geschehen ist Bühne. Jetzt funktioniert das Lesen aus dem Puffer und das Schreiben in die Datei nur, wenn ich 32-Bit-PCM-Codierung mit der folgenden Funktion verwende (auskommentiert ist der PCM-16-Bit-Code, der zu einer Zeitlupen-Sprachausgabe führt):
private void ProcessFrameOutput(AudioFrame frame)
{
//Making a copy of the audio frame buffer
var audioBuffer = frame.LockBuffer(AudioBufferAccessMode.Read);
var buffer = Windows.Storage.Streams.Buffer.CreateCopyFromMemoryBuffer(audioBuffer);
buffer.Length = audioBuffer.Length;
using (var dataReader = DataReader.FromBuffer(buffer))
{
dataReader.ByteOrder = ByteOrder.LittleEndian;
byte[] byteData = new byte[buffer.Length];
int pos = 0;
while (dataReader.UnconsumedBufferLength > 0)
{
/*Reading Float -> Int 32*/
/*With this code I can import raw wav file into the Audacity
using Signed 32-bit PCM Encoding, and it is working well*/
var singleTmp = dataReader.ReadSingle();
var int32Tmp = (Int32)(singleTmp * Int32.MaxValue);
byte[] chunkBytes = BitConverter.GetBytes(int32Tmp);
byteData[pos++] = chunkBytes[0];
byteData[pos++] = chunkBytes[1];
byteData[pos++] = chunkBytes[2];
byteData[pos++] = chunkBytes[3];
/*Reading Float -> Int 16 (Slow Motion)*/
/*With this code I can import raw wav file into the Audacity
using Signed 16-bit PCM Encoding, but when I play it, it's in
a slow motion*/
//var singleTmp = dataReader.ReadSingle();
//var int16Tmp = (Int16)(singleTmp * Int16.MaxValue);
//byte[] chunkBytes = BitConverter.GetBytes(int16Tmp);
//byteData[pos++] = chunkBytes[0];
//byteData[pos++] = chunkBytes[1];
}
WriteBytesToFile(byteData);
}
}
Kann jemand an einen Grund denken, warum dies geschieht? Liegt es daran, dass Int32 PCM größer ist und wenn ich Int16 verwende, verlängert es es und macht den Sound länger? Oder nehme ich es nicht richtig auf?
Hinweis: Ich habe versucht, Bytes direkt aus dem Puffer zu lesen, und dann als Rohdaten zu verwenden, aber es ist nicht als PCM auf diese Weise codiert. Das direkte Lesen von Int16/32 aus dem Puffer funktioniert auch nicht. Im obigen Beispiel verwende ich nur den Frame-Ausgangsknoten. Wenn ich einen Dateiausgabeknoten erstelle, der automatisch in die Raw-Datei schreibt, funktioniert er wirklich gut als 16-Bit-PCM, also stimmt etwas in meiner Callback-Funktion nicht, was bewirkt, dass es sich in einer langsamen Bewegung befindet.
Dank
Für die Zukunft zu überprüfen, wenn Sie eine beschädigte Rohdaten Probe zur Verfügung stellen würde, wäre Ihre Probleme leichter zu lösen. –