1

我想将我在 adobe air 中编写的应用程序移植到 xamarin。原因是我无法使用 flex 框架从 ipod 库中获取 mp3。现在我可以获取音频文件的列表,但我无法从资产中提取音频缓冲区。在 AS3 中,它是一个黑盒,但它始终将数据导出为具有以下属性的字节数组:

  • 采样率 44100Hz
  • 32 位
  • 浮点
  • 立体声

因为我不想重写所有算法,所以我想以与 AIR 中相同的格式“转换”所有歌曲。所以我写了这个

            AVAsset urlAsset = AVUrlAsset.FromUrl (url);
            NSError error = null;
            AVAssetReader reader = new AVAssetReader (urlAsset, out error);
            AVAssetTrack[] tracks = urlAsset.TracksWithMediaType (AVMediaType.Audio);

            NSMutableDictionary audioReadSettings = new NSMutableDictionary ();
            audioReadSettings.SetValueForKey (NSNumber.FromObject(AudioFormatType.LinearPCM), AVAudioSettings.AVFormatIDKey);
            audioReadSettings.SetValueForKey (NSNumber.FromBoolean(false), AVAudioSettings.AVLinearPCMIsBigEndianKey);
            audioReadSettings.SetValueForKey (NSNumber.FromBoolean(true), AVAudioSettings.AVLinearPCMIsFloatKey);   
            audioReadSettings.SetValueForKey (NSNumber.FromBoolean(false), AVAudioSettings.AVLinearPCMIsNonInterleaved);    
            audioReadSettings.SetValueForKey ((NSNumber)32, AVAudioSettings.AVLinearPCMBitDepthKey);
            /*
            audioReadSettings.SetValueForKey ((NSNumber)2, AVAudioSettings.AVNumberOfChannelsKey);
            audioReadSettings.SetValueForKey ((NSNumber)44100.0, AVAudioSettings.AVSampleRateKey);
            */

            AVAssetTrack track = tracks[0];
            AVAssetReaderTrackOutput outputReader = AVAssetReaderTrackOutput.FromTrack (track, audioReadSettings);

            if (!reader.CanAddOutput(outputReader)){
                return;
            }
            reader.AddOutput(outputReader);
            outputReader.Dispose();

            double sampleRate = 0;
            int channelCount = 0;
            foreach (CMFormatDescription formatDescription in track.FormatDescriptions){
                if (formatDescription.AudioFormats.Length != 0){
                    AudioFormat format = formatDescription.AudioFormats[0];
                    sampleRate = format.AudioStreamBasicDescription.SampleRate;
                    channelCount = format.AudioStreamBasicDescription.ChannelsPerFrame;
                    break;
                }
            }
            int bytesPerSample = 2 * channelCount;
            outputReader = (AVAssetReaderTrackOutput)reader.Outputs[0];

            if (!reader.StartReading()){
                return;
            }

            List flatBuffer = new List();
            List> buffers = new List>();

            string bufferString = string.Empty;

            for (int i = 0; i < 16; i++){
                CMSampleBuffer sampleBuffer = outputReader.CopyNextSampleBuffer();
                List buffer = extractBuffer(sampleBuffer, i, bytesPerSample, channelCount);
                flatBuffer.AddRange (buffer);
                sampleBuffer.Dispose();
            }

extractBuffer 方法看起来像这样

private List extractBuffer(CMSampleBuffer sampleBuffer, int index, int bytesPerSamples, int channelCount){
        CMBlockBuffer blockBuffer = sampleBuffer.GetDataBuffer ();
        int dataLength = (int)blockBuffer.DataLength;
        NSMutableData data = NSMutableData.FromLength (dataLength);
        blockBuffer.CopyDataBytes (0, (uint)dataLength, data.MutableBytes);

        int sampleCount = sampleBuffer.NumSamples;
        float[] resultBuffer = new float[sampleCount];
        unsafe{
            float* samples = (float*)data.MutableBytes;
            for (int i = 0; i < sampleCount; i++){
                float left = (float)*samples++;
                float right = left;
                if (channelCount == 2){
                    right = (float)*samples++;
                }
                resultBuffer [i] = (float)((left + right) / 2);
            }
        }
        List result = new List(resultBuffer);

        resultBuffer = null;
        blockBuffer.Dispose ();
        blockBuffer = null;
        return result;
}

请注意,为了稍后的分析,我将信号重新转换为单声道信号。

现在我应该在 xamarin 和 adobe air 中获得相同的 mp3 数据,但事实并非如此。大多数时候我得到相同的值,但不是相同的索引。我想 adobe 的工程师知道他们在做什么,所以我在这里错过了什么?

谢谢你的帮助

4

0 回答 0