C# 在Windows 10(UAP)上使用音频图提取PCM数据以生成Chromaprint指纹

C# 在Windows 10(UAP)上使用音频图提取PCM数据以生成Chromaprint指纹,c#,audio,win-universal-app,audio-fingerprinting,C#,Audio,Win Universal App,Audio Fingerprinting,我目前正在尝试编写一个Win 10应用程序,它使用chromaprint识别一首歌曲,并从acousticid.org获取数据 但我的方法是返回错误的值。 第一个问题是它返回许多值。我有很多数据是246秒对237秒。第二个值由fpcalc.exe返回 第二个问题是,我的ExtractPCM实现返回的值与我在开源项目中发现的工作实现完全不同。我不太懂音频,但我认为我的价值观是错误的 我用来测试代码的参考实现是。它使用BASS来提取PCM数据 BASS返回的数据从10.054零开始,然后继续: aw

我目前正在尝试编写一个Win 10应用程序,它使用chromaprint识别一首歌曲,并从acousticid.org获取数据

但我的方法是返回错误的值。 第一个问题是它返回许多值。我有很多数据是246秒对237秒。第二个值由fpcalc.exe返回

第二个问题是,我的ExtractPCM实现返回的值与我在开源项目中发现的工作实现完全不同。我不太懂音频,但我认为我的价值观是错误的

我用来测试代码的参考实现是。它使用BASS来提取PCM数据

BASS返回的数据从10.054零开始,然后继续:

await Task.Run(() =>
 {
     unsafe
     {
         var memoryByteAccess = refference as IMemoryBufferByteAccess;
         byte* p;
         uint capacity;

         memoryByteAccess.GetBuffer(out p, out capacity);
         chanels = (int)output.EncodingProperties.ChannelCount;
         sampleRate = (int)output.EncodingProperties.SampleRate;
         int length = Math.Min((int)(sampleRate * duratio) * chanels, (int)(capacity / sizeof(float)));
         float* b = (float*)(p);
         erg = new short[length];
         for (int i = 0; i < erg.Length; i++)
             erg[i] = (Int16)(b[i] * Int16.MaxValue);
         seconds = length / (double)output.EncodingProperties.SampleRate / chanels;
     }

 });
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-1-1 0 0 0 0 0-1 0 0 0 0 0 0 0 0 0 0 0 0 0-1 0 0 0 0

两秒标记末尾的最后一个值如下所示:

612 627 635 647 655 656 662 662 663 658

我的实现从10.528个零开始,后跟:

-1519411946213441121112573212414-2871512748609812973-31198130462878412844212481279715921652254413294-20448

13636-17580-18770-17639-29613-17604 10168-17608 20472-17618

我的眼睛看起来像

    public static async Task<PcmInfo> ExtractPcm(IStorageFile file)
    {
        int sampleRate = 0;
        int chanels = 0;
        double seconds = 0;
        short[] erg = null;
        var graphResult = await Windows.Media.Audio.AudioGraph.CreateAsync(new Windows.Media.Audio.AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media));
        using (var graph = graphResult.Graph)
        {
            var encodingProperties = Windows.Media.MediaProperties.AudioEncodingProperties.CreatePcm(22050, 1, 16);

            var fileResult = await graph.CreateFileInputNodeAsync(file);
            var fileInput = fileResult.FileInputNode;
            {
                var output = graph.CreateFrameOutputNode(encodingProperties);
                {

                    fileInput.AddOutgoingConnection(output);
                    var duratio = fileInput.Duration.TotalSeconds;
                    var taskSource = new TaskCompletionSource<object>();
                    fileInput.FileCompleted += (source, e) =>
                    {
                        graph.Stop();
                        output.Stop();
                        taskSource.TrySetResult(null);
                    };
                    graph.Start();
                    await taskSource.Task;

                    var audioFrame = output.GetFrame();
                    using (var lockedBuffer = audioFrame.LockBuffer(Windows.Media.AudioBufferAccessMode.ReadWrite))
                    {
                        using (var refference = lockedBuffer.CreateReference())
                        {
                            await Task.Run(() =>
                             {
                                 unsafe
                                 {
                                     var memoryByteAccess = refference as IMemoryBufferByteAccess;
                                     byte* p;
                                     uint capacity;
                                     memoryByteAccess.GetBuffer(out p, out capacity);
                                     chanels = (int)output.EncodingProperties.ChannelCount;
                                     sampleRate = (int)output.EncodingProperties.SampleRate;
                                     int length = (int)(capacity / sizeof(Int16));
                                     Int16* b = (Int16*)(p);
                                     erg = new short[length];
                                     for (int i = 0; i < erg.Length; i++)
                                         erg[i] = b[i];
                                     seconds = length / (double)output.EncodingProperties.SampleRate / chanels;
                                 }

                             });
                        }
                    }
                }
            }
            var sb = new StringBuilder();
            foreach (var item in erg.SkipWhile(y => y == 0).Take(sampleRate * 2))
            {
                sb.Append($"{item} ");
            }
            System.Diagnostics.Debug.WriteLine($"Leading zeros {erg.TakeWhile(y => y == 0).Count()} ");
            System.Diagnostics.Debug.WriteLine(sb);
            return new PcmInfo() { Data = erg, Seconds = seconds, SampleRate = sampleRate, Chanels = chanels };
        }

    }
公共静态异步任务提取PCM(IStorageFile文件)
{
int-sampleRate=0;
int香奈儿=0;
双秒=0;
short[]erg=null;
var graphResult=等待Windows.Media.Audio.AudioGraph.CreateAsync(新的Windows.Media.Audio.AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media));
使用(var-graph=graphResult.graph)
{
var encodingProperties=Windows.Media.MediaProperties.AudioEncodingProperties.CreatePcm(22050,1,16);
var fileResult=wait graph.CreateFileInputNodeAsync(文件);
var fileInput=fileResult.FileInputNode;
{
var output=graph.CreateFrameOutputNode(编码属性);
{
fileInput.AddOutgoingConnection(输出);
var duratio=fileInput.Duration.TotalSeconds;
var taskSource=new TaskCompletionSource();
fileInput.FileCompleted+=(源代码,e)=>
{
graph.Stop();
output.Stop();
taskSource.TrySetResult(null);
};
graph.Start();
等待taskSource.Task;
var audioFrame=output.GetFrame();
使用(var lockedBuffer=audioFrame.LockBuffer(Windows.Media.AudioBufferAccessMode.ReadWrite))
{
使用(var reference=lockedBuffer.CreateReference())
{
等待任务。运行(()=>
{
不安全的
{
var memoryByteAccess=引用为IMemoryBufferByteAccess;
字节*p;
单位容量;
GetBuffer(out p,out capacity);
香奈儿=(int)output.EncodingProperties.ChannelCount;
sampleRate=(int)output.EncodingProperties.sampleRate;
整数长度=(整数)(容量/大小(整数16));
Int16*b=(Int16*)(p);
erg=新短[长度];
for(int i=0;iy==0.Take)(sampleRate*2))
{
sb.追加($“{item}”);
}
System.Diagnostics.Debug.WriteLine($“前导零{erg.TakeWhile(y=>y==0.Count())”;
系统诊断调试写线(sb);
返回新的PcmInfo(){Data=erg,Seconds=Seconds,SampleRate=SampleRate,Chanels=Chanels};
}
}
AresRPG使用以下代码读取数据:

    public static System.Int16[] ExtractPcm(String file, out double seconds)
    {
        seconds = 0;
        int handle = Bass.BASS_StreamCreateFile(file, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_STREAM_PRESCAN);
        if (handle == 0)
        {
            BASSError error = Bass.BASS_ErrorGetCode();
            // System.Console.WriteLine("ERROR: " + error);
            return null;
        }
        long length = Bass.BASS_ChannelGetLength(handle);
        seconds = Bass.BASS_ChannelBytes2Seconds(handle, length);
        int mixHandle = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(22050, 1, BASSFlag.BASS_STREAM_DECODE);
        if (mixHandle == 0)
        {
            BASSError error = Bass.BASS_ErrorGetCode();
            // System.Console.WriteLine("ERROR: " + error);
            return null;
        }
        if (!Un4seen.Bass.AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixHandle, handle, BASSFlag.BASS_DEFAULT))
        {
            BASSError error = Bass.BASS_ErrorGetCode();
            // System.Console.WriteLine("ERROR: " + error);
            return null;
        }
        List<System.Int16> data = new List<System.Int16>();
        while (true)
        {
            Int16[] buffer = new Int16[512];
            int num = Bass.BASS_ChannelGetData(mixHandle, buffer, buffer.Length * 2);
            if (num == -1)
            {
                BASSError error = Bass.BASS_ErrorGetCode();
                Bass.BASS_StreamFree(handle);
                // System.Console.WriteLine("ERROR: " + error);
                return null;
            }
            for (int i = 0; i < num / 2; ++i)
            {
                if (i < buffer.Length)
                    data.Add(buffer[i]);
                else
                    throw new ApplicationException();
            }
            if (num < buffer.Length * 2)
                break;
        }
        Bass.BASS_StreamFree(handle);
        try
        {
            return data.ToArray();
        }
        catch (System.OutOfMemoryException)
        {
            System.GC.Collect();
            return null;
        }
    }
public static System.Int16[]ExtractPcm(字符串文件,输出双秒)
{
秒=0;
int handle=Bass.Bass_StreamCreateFile(文件,0,0,BASSFlag.Bass_STREAM_DECODE | BASSFlag.Bass_SAMPLE | MONO | BASSFlag.Bass_STREAM_PRESCAN);
如果(句柄==0)
{
BASSError error=Bass.Bass_ErrorGetCode();
//System.Console.WriteLine(“错误:+错误”);
返回null;
}
长长度=低音。低音信道长度(手柄);
秒=低音。低音信道字节2秒(手柄,长度);
int mixHandle=Un4seen.Bass.AddOn.Mix.BassMix.Bass\u Mixer\u StreamCreate(22050,1,BASSFlag.Bass\u STREAM\u DECODE);
if(mixHandle==0)
{
BASSError error=Bass.Bass_ErrorGetCode();
//System.Console.WriteLine(“错误:+错误”);
返回null;
}
if(!Un4seen.Bass.AddOn.Mix.BassMix.Bass\u Mixer\u StreamAddChannel(mixHandle,handle,bassfag.Bass\u默认))
{
BASSError error=Bass.Bass_ErrorGetCode();
//System.Console.WriteLine(“错误:+错误”);
返回null;
}
列表数据=新列表();
while(true)
{
Int16[]缓冲区=新的Int16[512];
int num=B