$./flite -t "test"frameIndex: 0maxFrameIndex: 0numChannels: 1numSamples: 7225sampleRate: 8000=== Now playing back. ===Waiting for playback to finish.frameIndex in callback: -2008986336maxFrameIndex in callback: 32655numChannels in callback: 152579008numSamples in callback: 0sampleRate in callback: 0Segmentation fault: 11 $./flite -t "test"frameIndex: 0maxFrameIndex: 0numChannels: 1numSamples: 7225sampleRate: 8000=== Now playing back. ===Waiting for playback to finish.frameIndex in callback: -71217888maxFrameIndex in callback: 32712numChannels in callback: 232979392numSamples in callback: 0sampleRate in callback: 0Segmentation fault: 11
这是audio.c文件中的相关代码,当我提供命令行参数-t时调用它.在进行了一些调试之后,我在playCallback()函数中标记了分段故障发生的兴趣区域.
static int playCallback( const voID *inputBuffer,voID *outputBuffer,unsigned long framesPerBuffer,const PaStreamCallbackTimeInfo* timeInfo,PaStreamCallbackFlags statusFlags,voID *userData ){ cst_wave *data = (cst_wave*)userData; short *rptr = &data->samples[data->frameIndex * data->num_channels]; short *wptr = (short*)outputBuffer; unsigned int i; int finished; unsigned int framesleft = cst_wave_maxFrameIndex(data) - cst_wave_frameIndex(data); (voID) inputBuffer; /* Prevent unused variable warnings. */ (voID) timeInfo; (voID) statusFlags; (voID) userData; printf("frameIndex in callback: %d\n",cst_wave_frameIndex(data)); printf("maxFrameIndex in callback: %d\n",cst_wave_maxFrameIndex(data)); printf("numChannels in callback: %d\n",cst_wave_num_channels(data)); printf("numSamples in callback: %d\n",cst_wave_num_samples(data)); printf("sampleRate in callback: %d\n\n",cst_wave_sample_rate(data)); if( framesleft < framesPerBuffer ) { /* final buffer... */ for( i=0; i<framesleft; i++ ) { *wptr++ = *rptr++; /* left */ if( cst_wave_num_channels(data) == 2 ) *wptr++ = *rptr++; /* right */ } for( ; i<framesPerBuffer; i++ ) { *wptr++ = 0; /* left */ if( cst_wave_num_channels(data) == 2) *wptr++ = 0; /* right */ } data->frameIndex += framesleft; finished = paComplete; } else { for( i=0; i<framesPerBuffer; i++ ) { *wptr++ = *rptr++; /* left */ if( cst_wave_num_channels(data) == 2 ) *wptr++ = *rptr++; /* right */ } cst_wave_set_frameIndex(data,framesPerBuffer); finished = paContinue; } return finished;}int play_wave(cst_wave *w){ PaStream* stream; PaStreamParameters outputParameters; cst_wave_set_frameIndex(w,0); cst_wave_set_maxFrameIndex(w,(cst_wave_num_samples(w) / cst_wave_sample_rate(w)) * cst_wave_num_channels(w) * sizeof(short)); int err = 0; err = Pa_Initialize(); outputParameters.device = Pa_GetDefaultOutputDevice(); if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); return -5; } printf("frameIndex: %d\n",cst_wave_frameIndex(w)); printf("maxFrameIndex: %d\n",cst_wave_maxFrameIndex(w)); printf("numChannels: %d\n",cst_wave_num_channels(w)); printf("numSamples: %d\n",cst_wave_num_samples(w)); printf("sampleRate: %d\n",cst_wave_sample_rate(w)); outputParameters.channelCount = cst_wave_num_channels(w); outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostAPISpecificStreamInfo = NulL; puts("=== Now playing back. ==="); err = Pa_OpenStream(&stream,NulL,/* no input */ &outputParameters,cst_wave_sample_rate(w),512,paClipOff,playCallback,&w); if( stream ) { err = Pa_StartStream( stream ); if( err != paNoError ) goto done; puts("Waiting for playback to finish."); while((err = Pa_IsstreamActive(stream)) == 1) Pa_Sleep(100); if( err < 0 ) goto done; err = Pa_CloseStream( stream ); if( err != paNoError ) goto done; puts("Done."); }done: Pa_Terminate(); free(cst_wave_samples(w));}
因为它是相关的,我还稍微修改cst_wave.h中的cst_wave结构,以便它包含我必须存储的数据,以及添加一些已经存在的#define:
typedef struct cst_wave_struct { const char *type; int frameIndex; int maxFrameIndex; int sample_rate; int num_samples; int num_channels; short *samples;} cst_wave;#define cst_wave_num_samples(w) (w?w->num_samples:0)#define cst_wave_num_channels(w) (w?w->num_channels:0)#define cst_wave_sample_rate(w) (w?w->sample_rate:0)#define cst_wave_samples(w) (w->samples)#define cst_wave_frameIndex(w) (w->frameIndex)#define cst_wave_maxFrameIndex(w) (w->maxFrameIndex)#define cst_wave_set_num_samples(w,s) w->num_samples=s#define cst_wave_set_num_channels(w,s) w->num_channels=s#define cst_wave_set_sample_rate(w,s) w->sample_rate=s#define cst_wave_set_frameIndex(w,s) w->frameIndex=s#define cst_wave_set_maxFrameIndex(w,s) w->maxFrameIndex=s
更新1:
按照@Rohan的建议,现在给我这个输出:
$./bin/flite -t "test"frameIndex: 0maxFrameIndex: 0numChannels: 1numSamples: 7225sampleRate: 8000=== Now playing back. ===Waiting for playback to finish.frameIndex in callback: 0maxFrameIndex in callback: 0numChannels in callback: 1numSamples in callback: 7225sampleRate in callback: 8000Done.flite(68929,0x7fff71c0d310) malloc: *** error for object 0x7fd6e2809800: pointer being freed was not allocated*** set a breakpoint in malloc_error_break to deBUGAbort trap: 6
为了解决这个问题,我删除了free(cst_wave_samples(w));.现在程序执行正常,没有可见的错误,但我的Mac上仍然没有音频输出.有什么建议么?
解决方法 你运气好我可以在自己的Mac上编译PortAudio和flite,并解决你的问题.除了之前提到的以外,您还有以下几个问题,我在下面的代码转储中已经解决了所有这些问题.
>次要:你不会一直使用你自己的cst_wave API.
>次要的:我喜欢把我的时间,如果块总是包含{}.这有一个防止神秘错误的习惯.
>最大帧被设置为零.这是因为在(cst_wave_num_samples(w)/ cst_wave_sample_rate(w))* cst_wave_num_channels(w)* sizeof(short)中,您除以采样率,大于您的采样数.假定整数除法是左关联的并截断,yadda yadda yadda为零.
>最大帧仍然是错误的,因为帧包括所有通道样本.因此,帧的数量对于信道的数量和样本本身的大小是不可知的.允许自己猜测,flite将样本误认为是帧,您的最大帧索引只是cst_wave_num_samples(w).否则它将是cst_wave_num_samples(w)/ cst_wave_num_channels(w).
> PortAudio的文档指出,在流变为无效后,您应该调用Pa_StopStream(流),无论您是否等待,直到它变得如此.
>我简化了回调,并对其进行了更正
>次要:一致使用您的API
> MAJOR:Ehm … cst_wave_set_frameIndex(data,framesPerBuffer);肯定是错的你固定在帧索引512而不是递增!这是因为您打开流时要求每个缓冲区512帧,而不是通过framePerBuffer递增帧索引,您将帧索引设置为framesPerBuffer.你没有这么做,因为你的maxFrameIndex是0,所以你退出.我修改它,以便帧索引增加 – 当然你的API.
这是代码,我采取了文件和清洁的自由,直到它接近我的优雅标准.请享用!
#include <stdio.h>#include <string.h>/** * Audio play callback. * * Follows the PaStreamCallback signature,wherein: * * @param input and * @param output are either arrays of interleaved samples or; if * non-interleaved samples were requested using the * paNonInterleaved sample format flag,an array of buffer * pointers,one non-interleaved buffer for each channel. * @param frameCount The number of sample frames to be processed by the * stream callback. * @param timeInfo Timestamps indicating the ADC capture time of the first * sample in the input buffer,the DAC output time of the * first sample in the output buffer and the time the * callback was invoked. See PaStreamCallbackTimeInfo and * Pa_GetStreamTime() * @param statusFlags Flags indicating whether input and/or output buffers * have been inserted or will be dropped to overcome * underflow or overflow conditions. * @param userData The value of a user supplIEd pointer passed to * Pa_OpenStream() intended for storing synthesis data * etc. */static int playCallback(const voID* inputBuffer,voID* outputBuffer,unsigned long framesPerBuffer,PaStreamCallbackFlags statusFlags,voID* userData){ (voID) inputBuffer; /* Prevent unused variable warnings. */ (voID) timeInfo; (voID) statusFlags; (voID) userData; /** * Compute current processing state. */ cst_wave* data; short* rptr; short* wptr; unsigned int framesleft,/* Number of frames of data remaining within the stream ***as a whole*** */ frames,/* Number of frames of data to be written for this buffer. */ framesPad,/* Number of frames of padding required within the final buffer. */ samples,/* Number of samples of data to be written for this buffer. */ samplesPad,/* Number of samples of padding required within the final buffer. */ numBytes,/* Number of bytes of data to be written for this buffer. */ numBytesPad;/* Number of bytes of padding required within the final buffer. */ int finalBuffer;/* Stores whether or not this is the final buffer. */ data = (cst_wave*)userData; rptr = &data->samples[cst_wave_frameIndex (data) * cst_wave_num_channels(data)]; wptr = (short*)outputBuffer; framesleft = cst_wave_maxFrameIndex(data) - cst_wave_frameIndex(data); finalBuffer = framesleft <= framesPerBuffer; frames = finalBuffer ? framesleft : framesPerBuffer; framesPad = framesPerBuffer - frames; samples = frames * cst_wave_num_channels(data); samplesPad = framesPad * cst_wave_num_channels(data); numBytes = samples * sizeof(short); numBytesPad = samplesPad * sizeof(short); /** * DeBUG code. Comment out in production. */ printf("framesleft in callback: %u\n",framesleft); printf("framesPerBuffer in callback: %lu\n",framesPerBuffer); printf("frames in callback: %u\n",frames); printf("frameIndex in callback: %d\n",cst_wave_sample_rate(data)); /** * Output data. We handle the final buffer specially,padding it with zeros. */ memcpy(wptr,rptr,numBytes); wptr += samples; rptr += samples; cst_wave_set_frameIndex(data,cst_wave_frameIndex(data) + frames); memset(wptr,numBytesPad); wptr += samplesPad; rptr += samplesPad; /** * Return a completion or continue code depending on whether this was the * final buffer or not respectively. */ return finalBuffer ? paComplete : paContinue;}/** * Play wave function. * * Plays the given cst_wave data as audio,blocking until this is done. */int play_wave(cst_wave *w){ PaStream* stream; PaStreamParameters outputParameters; int err; /** * Initialize custom fIElds in cst_wave struct. */ cst_wave_set_frameIndex(w,(cst_wave_num_samples(w))); // / cst_wave_sample_rate(w) * cst_wave_num_channels(w) * sizeof(short) /** * Initialize Port Audio device and stream parameters. */ err = Pa_Initialize(); outputParameters.device = Pa_GetDefaultOutputDevice(); if (outputParameters.device == paNoDevice){ fprintf(stderr,"Error: No default output device.\n"); return -5; } printf("frameIndex: %d\n",cst_wave_sample_rate(w)); outputParameters.channelCount = cst_wave_num_channels(w); outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostAPISpecificStreamInfo = NulL; /** * Open the stream for playback. */ puts("=== Now playing back. ==="); err = Pa_OpenStream(&stream,w); if(stream){ /** * Start the stream. */ err = Pa_StartStream(stream); if(err != paNoError){ goto done; } /** * Block while it plays. */ puts("Waiting for playback to finish."); while((err = Pa_IsstreamActive(stream)) == 1){ Pa_Sleep(100); } if(err < 0){ goto done; } /** * Stop and close the stream. Both are necessary. */ Pa_StopStream(stream); err = Pa_CloseStream(stream); if(err != paNoError){ goto done; } puts("Done."); } /** * Terminate and leave. */done: Pa_Terminate(); return 0;}总结
以上是内存溢出为你收集整理的c – 使用PortAudio输入音频全部内容,希望文章能够帮你解决c – 使用PortAudio输入音频所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)