AudioFileReadPackets提供奇怪的数据

时间:2014-07-03 21:28:53

标签: ios iphone buffer core-audio

我试图将音频录制到文件(工作),然后对该文件中的数据进行采样(给出奇怪的结果)。 仅供参考,我大致遵循此代码...... Extracting Amplitude Data from Linear PCM on the iPhone

我注意到了一些不同的结果。为简单起见,假设记录时间固定为1秒。

  1. 当采样高达8,000个样本/秒时,可变阵列(见代码)将列出8,000个条目,但只有前4,000个具有真实数据,最后4,000个点是相同的数值(确切数字)价值因运行而异。

  2. 与问题#1有些相关。当采样超过8,000个样本/秒时,前半部分样本(例如,10,000个样本中的5,000个,每秒10,000个样本,1秒)将看起来像真实数据,而后半部分的值将被固定为某个值(同样,这个确切的值会随着运行而变化)。从我的调试窗口看下面的代码片段,第一个数字是packetIndex,第二个数字是缓冲区值。

  3. 4996:-137

    4997:1043

    4998:-405

    4999:-641

    5000:195 注意从随机数据切换到5k的常量值,对于10k样本文件

    5001:195

    5002:195

    5003:195

    5004:195

    3。当麦克风收听扬声器播放1kHz正弦音并靠近并以每秒40,000个样本采样该音时,在电子表格中绘制的结果数据显示信号约为2kHz或两倍。

    我在这里做错了什么想法?

    这是我从麦克风录制音频的设置工作......

    -(void) initAudioSession {
    //    setup av session
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [audioSession setActive:YES error: nil];
        NSLog(@"audio session initiated");
    //    settings for the recorded file
        NSDictionary *recordSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
                                        [NSNumber numberWithFloat:SAMPLERATE],AVSampleRateKey,
                                        [NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
                                        [NSNumber numberWithInt:1],AVNumberOfChannelsKey,
                                        [NSNumber numberWithInt:16],AVEncoderBitRateKey,
                                        [NSNumber numberWithInt:AVAudioQualityMax],AVEncoderAudioQualityKey, nil];
    //    setup file name and location
        NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        fileURL = [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"input.caf"]];//caf or aif?
    //    initialize my new audio recorder
        newAudioRecorder = [[AVAudioRecorder alloc] initWithURL:fileURL settings:recordSettings error:nil];
    //    show file location so i can check it with some player
        NSLog(@"file path = %@",fileURL);
    //    check if the recorder exists, if so prepare the recorder, if not tell me in debug window
        if (newAudioRecorder) {
            [newAudioRecorder setDelegate:self];
            [newAudioRecorder prepareToRecord];
            [self.setupStatus setText:[NSString stringWithFormat:@"recorder ready"]];
        }else{
            NSLog(@"error setting up recorder");
        }
    }
    

    这是我加载录制文件并抓取数据的代码......

    //loads file and go thru values, converts data to be put into an NSMutableArray
    -(void)readingRainbow{
        //    get audio file and put into a file ID
        AudioFileID fileID;
        AudioFileOpenURL((__bridge CFURLRef)fileURL, kAudioFileReadPermission, kAudioFileCAFType /*kAudioFileAIFFType*/ , &fileID);
        //    get number of packets of audio contained in file
    //    instead of getting packets, i just set them to the duration times the sample rate i set
    //    not sure if this is a valid approach
        UInt64 totalPacketCount = SAMPLERATE*timer;
        //    get size of each packet, is this valid?
        UInt32 maxPacketSizeInBytes = sizeof(SInt32);
        //    setup to extract audio data
        UInt32 totPack32 = SAMPLERATE*timer;
        UInt32 ioNumBytes = totPack32*maxPacketSizeInBytes;
        SInt16 *outBuffer = malloc(ioNumBytes);
        memset(outBuffer, 0, ioNumBytes);
        //    setup array to put buffer samples in
        readArray = [[NSMutableArray alloc] initWithObjects: nil];
        NSNumber *arrayData;
        SInt16 data;
        int data2;
    
    
    //    this may be where i need help as well....
        //    process every packet
        for (SInt64 packetIndex = 0; packetIndex<totalPacketCount; packetIndex++) {
    // method description for reference..
    //        AudioFileReadPackets(<#AudioFileID inAudioFile#>, <#Boolean inUseCache#>, <#UInt32 *outNumBytes#>,
    //        <#AudioStreamPacketDescription *outPacketDescriptions#>, <#SInt64 inStartingPacket#>,
    //        <#UInt32 *ioNumPackets#>, <#void *outBuffer#>)
    //        extract packet data, not sure if i'm setting this up properly
            AudioFileReadPackets(fileID, false, &ioNumBytes, NULL, packetIndex, &totPack32, outBuffer);
    //        get buffer data and pass into mutable array
            data = outBuffer[packetIndex];
            data2=data;
            arrayData = [[NSNumber alloc] initWithInt:data2];
            [readArray addObject:arrayData];
    //        printf("%lld:%d\n",packetIndex,data);
            printf("%d,",data);
    
        }
    

    另外,我使用这种方法启动录音机......

    [newAudioRecorder recordForDuration:timer];
    

    Thots?我是一个菜鸟,所以非常感谢任何信息!

1 个答案:

答案 0 :(得分:1)

您可能正在录制16位样本,但尝试从文件数据中读取32位样本,因此只能找到一半的样本(其余样本可能是垃圾)。