在这里,我正在为一个连续录音音频系统编写一些代码.然后,当某个幅度阈值被破坏时,我尝试将音频录制一段时间.
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <time.h> #include <portaudio.h> #include <sndfile.h> #define FRAMES_PER_BUFFER (1024) #define SAMPLE_SIZE (4) typedef struct { uint16_t formatType; uint16_t numberOfChannels; uint32_t sampleRate; float* recordedSamples; } AudioData; AudioData initAudioData(uint32_t sampleRate,uint16_t channels,int type) { AudioData data; data.formatType = type; data.numberOfChannels = channels; data.sampleRate = sampleRate; return data; } float avg(float *data) { int elems = sizeof(data) / sizeof(data[0]); float sum = 0; for (int i = 0; i < elems; i++) { sum += fabs(*(data + i)); } return (float) sum / elems; } int main(void) { AudioData data = initAudioData(44100,2,paFloat32); PaStream *stream = NULL; PaError err = paNoError; int size = FRAMES_PER_BUFFER * data.numberOfChannels * SAMPLE_SIZE; float *sampleBlock = malloc(size); float *recordedSamples = NULL; time_t talking = 0; time_t silence = 0; if((err = Pa_Initialize())) goto done; PaStreamParameters inputParameters = { .device = Pa_GetDefaultInputDevice(),.channelCount = data.numberOfChannels,.sampleFormat = data.formatType,.suggestedLatency = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->defaultHighInputLatency,.hostApiSpecificStreamInfo = NULL }; if((err = Pa_OpenStream(&stream,&inputParameters,NULL,data.sampleRate,FRAMES_PER_BUFFER,paClipOff,NULL))) goto done; if((err = Pa_StartStream(stream))) goto done; for(int i = 0;;) { err = Pa_ReadStream(stream,sampleBlock,FRAMES_PER_BUFFER); if(avg(sampleBlock) > 0.000550) // talking { printf("You're talking! %d\n",i); i++; time(&talking); recordedSamples = realloc(recordedSamples,size * i); if (recordedSamples) memcpy(recordedSamples + ((i - 1) * size),size); // problem here writing to memory at i = 16? else free(recordedSamples); } else //silence { double test = difftime(time(&silence),talking); printf("Time diff: %g\n",test); if (test >= 1.5) { // TODO: finish code processing audio snippet talking = 0; free(recordedSamples); // problem freeing memory? } } } done: free(sampleBlock); Pa_Terminate(); return err; }
然而,代码有点精彩.有时,当我在Xcode中运行我的程序时,我得到以下输出:
06001
使用Xcode指向这一行是问题:
06002
06003
这两个错误有点令我困惑…任何建议?
解决方法
你正在写出分配的缓冲区的边界:
recordedSamples = realloc(recordedSamples,size * i); memcpy(recordedSamples + ((i - 1) * size),size);
realloc()分配一定数量的字节,这里size * i.生成的指针存储在具有float *类型的recordsSamples中.
memcpy()然后尝试将数据写入到记录样本((i – 1)* size)中,指针算术用于确定应写入的位置,由于recordsSamples的类型为float *,所以记录的样本X指向X的偏移量浮点值(不是X字节).
换句话说,recordingSamples((i – 1)* size指向recordSamples之后的内存位置((i – 1)* size * sizeof(float)),通常不在分配的缓冲区内,因为浮点大于单字节.
要解决这个问题,最大的问题是如果大小应该是多个字节或一些浮点数.这取决于您使用的API函数,我没有详细研究.
如果它是一些浮点数,那么您必须调整对malloc,realloc和memcpy等基本内存管理功能的调用,因为这些操作都是以字节为单位的.要取代malloc(size),你可以调用malloc(size * sizeof(float)).
如果大小确实是多个字节,那么将recordSamples作为char *,或者至少在使用字节偏移量进行指针运算(如memcpy((char *)recordsSamples …)之前将其转换为更合理的方式).