我使用 odroidN2+ 和音频接口来记录声音数据 24/7。录制几个文件后,程序挂起。 当我用 valgrind 检查程序来检查堆摘要时,它提到如下。我怀疑这个问题是由于 portaudio 库造成的。因此,我在odroidN2+中编译了portaudio库,但问题仍然存在。
==1309067== HEAP SUMMARY:
==1309067== in use at exit: 42,461 bytes in 81 blocks
==1309067== total heap usage: 14,115 allocs, 14,034 frees, 1,489,720 bytes allocated
==1309067==
==1309067== 11 bytes in 1 blocks are definitely lost in loss record 3 of 72
==1309067== at 0x4849D8C: malloc (in /usr/lib/aarch64-linux-gnu/valgrind/vgpreload_memcheck-arm64-linux.so)
==1309067== by 0x10A383: main (in /home/odroid/acoustic/Recorder/Recorder_N2plus_10min)
==1309067==
==1309067== 112 bytes in 1 blocks are definitely lost in loss record 54 of 72
==1309067== at 0x484C0A4: calloc (in /usr/lib/aarch64-linux-gnu/valgrind/vgpreload_memcheck-arm64-linux.so)
==1309067== by 0x6243C2F: ???
==1309067== by 0x4B4BD03: ??? (in /usr/lib/aarch64-linux-gnu/libasound.so.2.0.0)
==1309067== by 0x4B4C2F7: ??? (in /usr/lib/aarch64-linux-gnu/libasound.so.2.0.0)
==1309067== by 0x4B4F2CF: snd_pcm_open (in /usr/lib/aarch64-linux-gnu/libasound.so.2.0.0)
==1309067== by 0x48A6593: ??? (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x48A8B83: ??? (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x48AB60B: PaAlsa_Initialize (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x489F723: Pa_Initialize (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x10A4FB: main (in /home/odroid/acoustic/Recorder/Recorder_N2plus_10min)
==1309067==
==1309067== 1,360 bytes in 1 blocks are definitely lost in loss record 63 of 72
==1309067== at 0x484C0A4: calloc (in /usr/lib/aarch64-linux-gnu/valgrind/vgpreload_memcheck-arm64-linux.so)
==1309067== by 0x62572AB: ???
==1309067== by 0x4B4BD03: ??? (in /usr/lib/aarch64-linux-gnu/libasound.so.2.0.0)
==1309067== by 0x4B4C2F7: ??? (in /usr/lib/aarch64-linux-gnu/libasound.so.2.0.0)
==1309067== by 0x4B4F2CF: snd_pcm_open (in /usr/lib/aarch64-linux-gnu/libasound.so.2.0.0)
==1309067== by 0x48A6593: ??? (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x48A8B83: ??? (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x48AB60B: PaAlsa_Initialize (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x489F723: Pa_Initialize (in /usr/lib/aarch64-linux-gnu/libportaudio.so.2.0.0)
==1309067== by 0x10A4FB: main (in /home/odroid/acoustic/Recorder/Recorder_N2plus_10min)
==1309067==
==1309067== LEAK SUMMARY:
==1309067== definitely lost: 1,483 bytes in 3 blocks
==1309067== indirectly lost: 0 bytes in 0 blocks
==1309067== possibly lost: 0 bytes in 0 blocks
==1309067== still reachable: 40,978 bytes in 78 blocks
==1309067== suppressed: 0 bytes in 0 blocks
==1309067== Reachable blocks (those to which a pointer was found) are not shown.
==1309067== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1309067==
==1309067== For lists of detected and suppressed errors, rerun with: -s
==1309067== ERROR SUMMARY: 160 errors from 23 contexts (suppressed: 0 from 0)
我可以知道如何解决这个录音挂起问题吗? 我的录音如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <portaudio.h>
#include <sndfile.h>
#include <time.h>
#include <libconfig.h>
#include <pthread.h>
#define FRAMES_PER_BUFFER (512)
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#elif 0
#else
#endif
const char * CurrentDateTime();
char* concat(char *s1, char *s2);
char wavefilename[45];
char equip[15];
SNDFILE *outfileCB;
SF_INFO sfinfo;
char * FileNameHead;
int filesize,NUM_CHANNELS,SAMPLE_RATE,duration;
typedef struct
{
int frameIndex;
int maxFrameIndex;
SAMPLE *recordedSamples;
}
paTestData;
static int recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{ printf("Being RecordCallBack *************** \n");
int finished;
static int totalRead = 0;
(void)outputBuffer;
(void)timeInfo;
(void)statusFlags;
(void)userData;
finished = paContinue;
if (totalRead * NUM_CHANNELS * 2 > filesize)
{
sf_close(outfileCB);
char * BUFF_Time;
BUFF_Time = CurrentDateTime();
char* s4=concat(FileNameHead,BUFF_Time);
char* outfilename=concat(s4,".wav");
free(s4);
if (!(outfileCB = sf_open(outfilename, SFM_WRITE, &sfinfo)))
{
puts(sf_strerror(NULL));
return 1;
};
sleep(1);
copyString(wavefilename,outfilename);
free(outfilename);
totalRead = 0;
}
int framesWritten = sf_writef_float(outfileCB, (const SAMPLE*)inputBuffer, framesPerBuffer);
totalRead+= framesPerBuffer;
return finished;
}
const char * CurrentDateTime()
{
time_t raw_time;
raw_time=time(NULL);
static char strbuffer[16];
strftime(strbuffer,16,"%m%d%Y_%H%M%S",localtime(&raw_time));
return strbuffer;
}
char* concat(char *s1, char *s2)
{
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
char *result = malloc(len1+len2+1);
memcpy(result, s1, len1);
memcpy(result+len1, s2, len2+1);
return result;
}
int main(void);
int main(void)
{
PaStreamParameters inputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int numSamples;
int numBytes;
int DeviceIdTarget;
int isfocusrite;
printf("patest_record.c\n"); fflush(stdout);
config_t cfg;
const char *EquipmentCC;
const char *site;
const char *area;
filesize=0;
NUM_CHANNELS=0;
config_init(&cfg);
if(! config_read_file(&cfg, "acoustic.cfg"))
{
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return(EXIT_FAILURE);
}
filesize=SAMPLE_RATE*NUM_CHANNELS*duration*2;
copyString(equip,EquipmentCC);
data.maxFrameIndex = FRAMES_PER_BUFFER;
data.frameIndex = 0;
numSamples = FRAMES_PER_BUFFER * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
SAMPLE recordedSamplesArr[numBytes];
// data.recordedSamples = recordedSamplesArr;
data.recordedSamples = (SAMPLE *) malloc( numBytes );
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
goto done;
}
for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
memset(&sfinfo, 0, sizeof(sfinfo));
sfinfo.samplerate = SAMPLE_RATE;
sfinfo.channels = NUM_CHANNELS;
sfinfo.frames = 0;
sfinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16);
char* Equipment=malloc(strlen(EquipmentCC)+1);
strcpy(Equipment,EquipmentCC);
char * BUFF_Time;
BUFF_Time = CurrentDateTime();
char* s1 = concat(site, "_");
char* s2 = concat(s1,area);
free(s1);
char* s21 = concat(s2, "_");
free(s2);
char* s3=concat(s21,Equipment);
free(s21);
FileNameHead=concat(s3,"_");
free(s3);
char* s4=concat(FileNameHead,BUFF_Time);
char* outfilename=concat(s4,".wav");
copyString(wavefilename,outfilename);
free(s4);
config_destroy(&cfg);
if (!(outfileCB = sf_open(outfilename, SFM_WRITE, &sfinfo)))
{
puts(sf_strerror(NULL));
return 1;
};
free(outfilename);
err = Pa_Initialize();
if (err != paNoError) goto done;
int numDevices =Pa_GetDeviceCount();
if (numDevices < 0)
{
err = numDevices;
goto done;
}
DeviceIdTarget=1;
const PaDeviceInfo *deviceInfo;
const PaHostApiInfo *apiInfo;
for (i = 0; i<numDevices; i++)
{
deviceInfo = Pa_GetDeviceInfo(i);
apiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
isfocusrite=checkStringMatch((char *)deviceInfo->name, "Scarlett");
if(isfocusrite&(deviceInfo->maxInputChannels>1)) DeviceIdTarget=i;
if(deviceInfo->maxInputChannels==1) DeviceIdTarget=i;
}
inputParameters.device = DeviceIdTarget;
if (inputParameters.device == paNoDevice) {
goto done;
}
inputParameters.channelCount = NUM_CHANNELS;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
recordCallback,
&data);
if (err != paNoError) goto done;
err = Pa_StartStream(stream);
if (err != paNoError) goto done;
fflush(stdout);
getchar();
err = Pa_CloseStream(stream);//
if (err != paNoError) goto done;
sf_close(outfileCB);
free(FileNameHead);
cleanup:
free(data.recordedSamples);
done:
Pa_Terminate();
if (err != paNoError)
{
err = 1;
}
return err;
free(Equipment);
}
你有 UB(未定义行为)。
site
是未初始化
并且, site
是 const char *
,因此传递给 concat
arg char *
将被标记为 -Wall
。
即使有:
char *site = NULL;
,concat
也需要更改:
char *
concat(const char *s1, const char *s2)
{
size_t len1 = (s1 != NULL) ? strlen(s1) : 0;
size_t len2 = (s2 != NULL) ? strlen(s2) : 0;
char *result = malloc(len1 + len2 + 1);
if (s1 != NULL)
memcpy(result, s1, len1);
if (s2 != NULL)
memcpy(result + len1, s2, len2);
result[len1 + len2] = 0;
return result;
}
与
FileNameHead
同样的问题