我试图让 flite speech synthesis library在我的Mac上工作,但是我的声音架构在flite库中不受支持.要解决这个问题,我使用 PortAudio播放合成音频;所以我不得不在audio.c文件中进行一些黑客攻击以获得使用该库的空白.我设法在GNU AutoTools处理一段时间之后,将所有的编译都很好,然后我运行该程序并得到这个输出:
$./flite -t "test"
frameIndex: 0
maxFrameIndex: 0
numChannels: 1
numSamples: 7225
sampleRate: 8000
=== Now playing back. ===
Waiting for playback to finish.
frameIndex in callback: -2008986336
maxFrameIndex in callback: 32655
numChannels in callback: 152579008
numSamples in callback: 0
sampleRate in callback: 0
Segmentation fault: 11  

$./flite -t "test"
frameIndex: 0
maxFrameIndex: 0
numChannels: 1
numSamples: 7225
sampleRate: 8000
=== Now playing back. ===
Waiting for playback to finish.
frameIndex in callback: -71217888
maxFrameIndex in callback: 32712
numChannels in callback: 232979392
numSamples in callback: 0
sampleRate in callback: 0
Segmentation 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: 0
maxFrameIndex: 0
numChannels: 1
numSamples: 7225
sampleRate: 8000
=== Now playing back. ===
Waiting for playback to finish.
frameIndex in callback: 0
maxFrameIndex in callback: 0
numChannels in callback: 1
numSamples in callback: 7225
sampleRate in callback: 8000

Done.
flite(68929,0x7fff71c0d310) malloc: *** error for object 0x7fd6e2809800: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort 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输入音频的更多相关文章

  1. Html5原创俄罗斯方块(基于canvas)

    这篇文章主要介绍了Html5原创俄罗斯方块(基于canvas)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 使用最新的Flurry SDK和ios4重新启动应用程序

    我真的希望这对我来说只是一个愚蠢的错误.我很高兴使用Flurry但这样的事情会导致我的应用被拒绝.解决方法我写了关于这个的Flurry,他们很快回到我身边,他们会调查这个.大约一个星期后,他们回信并表示他们已经在v2.6中修复了它,现在可用了.我似乎无法重现这个问题.不是说我很棒或者什么,但我还是单枪匹马地解决了这个问题.

  3. 如何在Xcode 4.1中调试OpenCL内核?

    我有一些OpenCL内核没有做他们应该做的事情,我很想在Xcode中调试它们.这可能吗?当我在我的内核中使用printf()时,OpenCL编译器总是给我一大堆错误.解决方法将格式字符串转换为constchar*似乎可以解决此问题.这适用于Lion:这有上述错误:

  4. swift 数据类型转换 string 转换为 int, int转换为string 等等 string转换为nsmutablestring

    bytheway:刚接触swift不就,学到的东西比较浅~~,但是有问题可以在评论里说说,我每天上,一起成长~~早晚小牛长成大牛,~more牛~~~牛的立方~~gogo

  5. 【swift_1】swift基本语法及事例Demo

    语法类的文档网上比较多,我这里参考:Swift基本语法事例Demo:链接:http://pan.baidu.com/s/1jGCINCq密码:5mdk语法须知2个不需要不需要编写main函数:全局作用域中的代码会被自动当做程序的入口点(从上往下执行)不需要在每一条语句后面加上分号letradius=10你喜欢的话,也可以加上letradius=10;有一种情况必须加分号:同一行代码上有多条语句时1

  6. 数组的enumerate(swift)

    数组的enumerateby伍雪颖letarr:Array=[1,2,216)">3,216)">4,216)">5]varresult=0forinenumerate{result+=num}println

  7. swift语言的学习笔记十二(初始化方法)

    所以Swift有了超级严格的初始化方法。与designated初始化方法对应的是在init前加上convenience关键字的初始化方法。所有的convenience初始化方法都必须调用同一个类中的designated初始化完成设置,另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。这样的一个最大的好处是可以保证依赖于某个designated初始化方法的convenience一直可以被使用。这在要求子类不直接使用父类中的convenience初始化方法时会非常有帮

  8. Swift 柯里化(currying)和反柯里化(uncurrying)

    //DemoofcurryingfuncaddTwoNums(a:Int)(num:Int)->Int{returna+num}letaddToFour=addTwoNums(4)letresult=addToFour(num:6)print("result:\(result)")funcgreaterThan(comparor:Int)(input:Int)->Bool{returninput>

  9. 从零学习Swift&lt;2&gt;

    ,可以强行解包注意:必须要确保解包后的值不是nil,否则会报错常见错误unexpectedlyfoundnilwhileunwrappinganOptionalvalue翻译在[解包]一个可选值时发现nil??运算符可以用于判断变量/常量的数值是否是nil,如果是则使用后面的值替代在使用Swift开发时,??

  10. 挺好的一篇总结文(等有空时看看)

    最近几天的感受是,Swift并不像我上一篇表达自己初步看法的文章里所说的那样,相对于objc来说有更好的学习曲线。另外一种类型是复合类型,包括函数和多元组。它们在使用的时候不会被命名,而是由Swift内部自己定义。在Swift的世界中,一切看得到的东西,都一定属于某一种类型。这也正式Swift的类型的一种很常见的组织方式。而当我们检查到Array的时候,发生了一点神奇的事情。这里的原因其实在Apple的官方文档中有一些说明。

随机推荐

  1. 从C到C#的zlib(如何将byte []转换为流并将流转换为byte [])

    我的任务是使用zlib解压缩数据包(已接收),然后使用算法从数据中生成图片好消息是我在C中有代码,但任务是在C#中完成C我正在尝试使用zlib.NET,但所有演示都有该代码进行解压缩(C#)我的问题:我不想在解压缩后保存文件,因为我必须使用C代码中显示的算法.如何将byte[]数组转换为类似于C#zlib代码中的流来解压缩数据然后如何将流转换回字节数组?

  2. 为什么C标准使用不确定的变量未定义?

    垃圾价值存储在哪里,为什么目的?解决方法由于效率原因,C选择不将变量初始化为某些自动值.为了初始化这些数据,必须添加指令.以下是一个例子:产生:虽然这段代码:产生:你可以看到,一个完整的额外的指令用来移动1到x.这对于嵌入式系统来说至关重要.

  3. 如何使用命名管道从c调用WCF方法?

    更新:通过协议here,我无法弄清楚未知的信封记录.我在网上找不到任何例子.原版的:我有以下WCF服务我输出添加5行,所以我知道服务器是否处理了请求与否.我有一个.NET客户端,我曾经测试这一切,一切正常工作预期.现在我想为这个做一个非托管的C客户端.我想出了如何得到管道的名称,并写信给它.我从here下载了协议我可以写信给管道,但我看不懂.每当我尝试读取它,我得到一个ERROR_broKEN_P

  4. “这”是否保证指向C中的对象的开始?

    我想使用fwrite将一个对象写入顺序文件.班级就像当我将一个对象写入文件时.我正在游荡,我可以使用fwrite(this,sizeof(int),2,fo)写入前两个整数.问题是:这是否保证指向对象数据的开始,即使对象的最开始可能存在虚拟表.所以上面的操作是安全的.解决方法这提供了对象的地址,这不一定是第一个成员的地址.唯一的例外是所谓的标准布局类型.从C11标准:(9.2/20)Apointe

  5. c – 编译单元之间共享的全局const对象

    当我声明并初始化一个const对象时.两个cpp文件包含此标头.和当我构建解决方案时,没有链接错误,你会得到什么如果g_Const是一个非const基本类型!PrintInUnit1()和PrintInUnit2()表明在两个编译单元中有两个独立的“g_Const”具有不同的地址,为什么?

  6. 什么是C名称查找在这里? (&amp;GCC对吗?)

    为什么在第三个变体找到func,但是在实例化的时候,原始变体中不合格查找找不到func?解决方法一般规则是,任何不在模板定义上下文中的内容只能通过ADL来获取.换句话说,正常的不合格查找仅在模板定义上下文中执行.因为在定义中间语句时没有声明func,并且func不在与ns::type相关联的命名空间中,所以代码形式不正确.

  7. c – 在输出参数中使用auto

    有没有办法在这种情况下使用auto关键字:当然,不可能知道什么类型的.因此,解决方案应该是以某种方式将它们合并为一个句子.这可用吗?解决方法看起来您希望默认初始化给定函数期望作为参数的类型的对象.您无法使用auto执行此操作,但您可以编写一个特征来提取函数所需的类型,然后使用它来声明您的变量:然后你就像这样使用它:当然,只要你重载函数,这一切都会失败.

  8. 在C中说“推动一切浮动”的确定性方式

    鉴于我更喜欢将程序中的数字保留为int或任何内容,那么使用这些数字的浮点数等效的任意算术最方便的方法是什么?说,我有我想写通过将转换放在解析的运算符树叶中,无需将表达式转化为混乱是否可以使用C风格的宏?应该用新的类和重载操作符完成吗?解决方法这是一个非常复杂的表达.更好地给它一个名字:现在当您使用整数参数调用它时,由于参数的类型为double,因此使用常规的算术转换将参数转换为double用C11lambda……

  9. objective-c – 如何获取未知大小的NSArray的第一个X元素?

    在objectiveC中,我有一个NSArray,我们称之为NSArray*largeArray,我想要获得一个新的NSArray*smallArray,只有第一个x对象…

  10. c – Setprecision是混乱

    我只是想问一下setprecision,因为我有点困惑.这里是代码:其中x=以下:方程的左边是x的值.1.105=1.10应为1.111.115=1.11应为1.121.125=1.12应为1.131.135=1.14是正确的1.145=1.15也正确但如果x是:2.115=2.12是正确的2.125=2.12应为2.13所以为什么在一定的价值是正确的,但有时是错误的?请启发我谢谢解决方法没有理由期望使用浮点系统可以正确地表示您的帖子中的任何常量.因此,一旦将它们存储在一个双变量中,那么你所拥有的确切的一

返回
顶部