【问题标题】:Segmentation Error 11 in C while writing a file to disk and using buffers将文件写入磁盘并使用缓冲区时 C 中的分段错误 11
【发布时间】:2014-11-23 15:49:49
【问题描述】:

该程序旨在创建一个输出正弦波文件,其中包含用户输入的持续时间、幅度、采样率和频率,用值填充缓冲区并应用短启动和衰减斜坡,然后再用数据写入新的 .aiff 文件.

虽然我的程序编译得很好,但在使用参数运行时会遇到“分段错误 11”,经过一些快速的谷歌搜索后,它似乎与内存不足有关。我检查了我的代码几次(主要是处理缓冲区大小和指向它的指针的区域)。

   /* playsine.c */
/* Creates a sine wave audio file with input outfile - duration - amplitude - sampling 
    rate - frequency */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <portsf.h>

int makeSine(float *buffer, double amplitude, long numFrames, double sineFreq,
             double samplingPeriod){
    long i;
    double time;
    double twoPi = 2 * M_PI;
    for(i = 0, time = 0; i < numFrames; i++){
        buffer[i] = amplitude * sin(twoPi * sineFreq * time);
        time += samplingPeriod;
        }
    return i;
    }



   long attack(float *buffer, long attackFrames){
    long i = 0;
    double factor = 0.0, increment = 1.0/attackFrames;
    while(factor <= 1.0 && i < attackFrames){
        buffer[i] = factor * buffer[i];
        factor += increment;
        ++i;
        }
    return i;
    }

long decay(float *endBuffer, long decayFrames){
    long i = 0;
    double factor = 1.0, decrement = 1.0/decayFrames;
    while(factor >= 0.0 && i < decayFrames){
        endBuffer[i] = decayFrames * endBuffer[i];
        factor -= decrement;
        ++i;
        }
    return i;
    }

enum {nameArg, outArg, durArg, ampArg, sampArg, freqArg, numArg};

int main(int argc, char* argv[]){

    if(argc < numArg){
        printf("Usage:\toutfile.aiff\tduration(s)\tamplitude(0-1)\tsampling rate\t\
        frequency(hz)\n");
        return 1;
        }
    if(psf_init()){
        printf("Error: Unable to open portsf library\n");
        return 1;
        }

    PSF_PROPS props;
    int outfile;
    long numFrames, samplingRate = atol(argv[sampArg]);
    double amps = atof(argv[ampArg]), samplingPeriod = 1.0/samplingRate;
    double sineFreq = atof(argv[freqArg]), attackFrames = 0.005 * samplingRate;
    double decayFrames = 0.01 * samplingRate;
    float *buffer, duration = atof(argv[durArg]);   
    numFrames = (long)duration * samplingRate;
    float *endBuffer = buffer + (numFrames - (long)decayFrames);

//Fill structure    
    props.srate = samplingRate;
    props.chans = 1;
    props.samptype = PSF_SAMP_16;
    props.format = PSF_AIFF;
    props.chformat = MC_MONO;


//Assign buffer
    buffer = (float*)malloc(numFrames * props.chans * sizeof(float));
    if(buffer == 0){
        printf("Error: unable to allocate buffer\n");
        return 1;
    }else{
//Fill buffer
        if(makeSine(buffer, amps, numFrames, sineFreq, samplingPeriod) != numFrames){
            printf("Error: unable to create sinewave\n");
            return 1;
            }
        attack(buffer, attackFrames);
        decay(endBuffer, decayFrames);
        }

//Create an outfile
    outfile = psf_sndCreate(argv[outArg], &props, 0, 0, PSF_CREATE_RDWR);
    if(outfile < 0){
        printf("Error: unable to create %s\n", argv[outArg]);
        return 1;
        }
//Write buffer to file          
    printf("Writing %s ...\n", argv[outArg]);
    if(psf_sndWriteFloatFrames(outfile, buffer, numFrames) != numFrames){
        printf("Warning: error writing %s\n", argv[outArg]);
        return 1;
        }
//Close file    
    if(psf_sndClose(outfile)){
        printf("Warning: error closing %s\n", argv[outArg]);
        return 1;
        }

    psf_finish();
    return 1;
}

【问题讨论】:

  • 哪些输入有效,哪些输入导致崩溃?
  • 我不太明白这个问题;以前(没有攻击和衰减函数),该程序在所有参数上都可以正常工作并输出正确的文件和格式,它只是使用新的“攻击”和“衰减”函数崩溃。抱歉,我应该更好地表达我的问题。

标签: c audio segmentation-fault buffer


【解决方案1】:

我在decay()attack() 看到的两个直接问题:

long attack (float *buffer, long attackFrames) {
    long i;
    ...
        buffer[i] = factor * buffer[i];  //Oops, i is never initialized

变量i 从未初始化。这是未定义的行为,很可能导致崩溃。我假设您实际上想要执行以下操作:

long attack (float *buffer, long attackFrames) {
    long i = 0;
    double factor = 0.0, increment = 1.0/attackFrames;

    while(factor <= 1.0 && i < attackFrames) {
        buffer[i] = factor * buffer[i];
        factor += increment;
        ++i;
    }

    return i;
}

编辑:另一个问题是您使用endBuffer引用未初始化的内存:

 float *buffer;              // Buffer not initialized
 float *endBuffer = buffer + (numFrames - (long)decayFrames);  // Oops!
 ...
 buffer = (float*)malloc(numFrames * props.chans * sizeof(float)); 
 //endBuffer still points to buffer's original address which is who-knows-where

你应该在使用malloc()分配buffer之后分配endBuffer

【讨论】:

  • 是的,我应用了你的建议(我需要循环与缓冲区交互),但它仍然返回错误。
  • 添加了endBuffer 的另一个问题。注意我需要你的命令行输入来实际测试代码。
  • 我稍后会尝试您的修改 - 我一直在测试的输入是 ./playsine 10 1 44100 1000
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
  • 2019-04-13
  • 2015-08-20
  • 1970-01-01
  • 2016-08-12
相关资源
最近更新 更多