c - 为什么我的数组在 C 中返回错误的值?

标签 c arrays function pointers libsndfile

我正在尝试使用 libsndfile 库在音频文件之间读取/写入信息。

我已设法读取原始文件,并使用“水印”值编写其副本。

我现在要做的就是打印值不为 0 的任何索引。

但是,当我调用 printBuffer() 函数时,即使在 Debug模式下,它也会返回全 0,我可以看到缓冲区中的值不为零/每次迭代都会发生变化。

我是否错误地调用了缓冲区数组?

我还是 C 语言新手,因此如果您有任何建议,我们将不胜感激。

谢谢。

代码:

#define _CRT_SECURE_NO_DEPRECATE    
#include <stdio.h>
#include <stdlib.h>
#include <sndfile.h>
#include <time.h>

#define MAX_CHANNEL 2
#define BUF_SIZE 1024

int numItems(int frames, int channels);
void printInfo(int frames, int channels, int sampleRate);
void watermark(double *buffer, int count, int channels);
void watermark2(double *buffer, int count);
void readFile(int fileNumber);
void printBuffer(double *buffer, size_t count);

int main(void)
{

    int chosenFile, answer;

    printf("Please select the file you want to read\n");
    printf("1. File1\n");
    printf("2. File2\n");
    printf("3. File3\n");
    printf("4. File4\n");
    printf("5. File5\n");
    scanf("%d", &chosenFile);   

    processFile(chosenFile);
    /*
    Put boolean here to check whether to process the original file or the new one
    */
    printf("Would you like to read the new file?\n");
    printf("1. Yes\n");
    printf("2. No\n");
    scanf("%d", &answer);

    if (answer == 1)
    {
        readFile(chosenFile);
    }

}

int processFile(int fileNumber)
{
    /*READING FILE*/

    static double buffer[BUF_SIZE];
    SF_INFO info;
    SNDFILE *infile,*outfile;
    int readCount, i;


    /*
    Put boolean here to check whether it should read the original files, or the new output files

    */
    char *Files[] = { "File1.wav", "File2.wav", "File3.wav"
        , "File4.wav", "DFile5.wav" };

    char *Files2[] = { "File1Output.wav", "File2Output.wav", "File3Output.wav"
        , "File4Output.wav", "File5Output.wav" };

    char *inputFile = Files[fileNumber - 1];

    if (!(infile = sf_open(inputFile, SFM_READ, &info)))
    {
        printf("Not able to open input file %s.\n", inputFile);
        puts(sf_strerror(NULL));
        return 1;
    };


    printf("You have opened: %s\n", Files[fileNumber - 1]);
    printInfo( info.frames, info.channels, info.samplerate);
    int num = numItems(info.frames, info.channels);
    printf("Buffer(frames*channels): %d \n", num);


    /*WRITING FILE*/    
    char *outputFile = Files2[fileNumber - 1];
    printf("Your file has been saved in the following location: %s\n", outputFile);


    if (!(outfile = sf_open(outputFile, SFM_WRITE, &info)))
    {
        printf("Not able to open output file %s.\n", outputFile);
        puts(sf_strerror(NULL));
        return 1;
    };

    /*
    Actual buffer size is numItems, somehow can't declare buffer as buffer[numItems]
    BUF_SIZE is set to 1024, which means that it reads the data in chunks of 1024 frames
    it will keep writing in 1024 chuncks until all numItems have been written (numItems/BUF_SIZE)
    Needs to be on a while loop otherwise it will only write the first 1024 frames of the file
    */


    while ((readCount = sf_read_double(infile, buffer, BUF_SIZE)))
    {   

        watermark(buffer, readCount, info.channels);
        sf_write_double(outfile, buffer, readCount);
    };


    for (i = 0; i < sizeof(buffer) / sizeof *buffer; i++)
    {
        printBuffer(buffer, sizeof(buffer)/sizeof *buffer);
    }


    /*
    Can only close SF_open once both reading/writing has been done
    if you close infile after the read, it's not able to copy the audio
    data from infile to write into outfile
    */
    sf_close(infile);
    sf_close(outfile);


    return;
}

void readFile(int fileNumber)
{
    SF_INFO info;
    SNDFILE *infile;

    char *Files[] = { "File1Output.wav", "File2Output.wav", "File3Output.wav"
        , "File4Output.wav", "File5Output.wav" };

    char *inputFile = Files[fileNumber - 1];

    infile = sf_open(inputFile, SFM_READ, &info);

    printf("You have opened: %s\n", Files[fileNumber - 1]);
    printInfo(info.frames, info.channels, info.samplerate);

    sf_close(infile);

    return;


}

int numItems(int frames, int channels)
{
    int numItems = frames * channels;
    return numItems;
}
void printInfo(int frames, int channels, int sampleRate)
{
    printf("Number of Frames = %d\n", frames);
    printf("Number of Channels = %d\n", channels);
    printf("Sample Rate = %d\n", sampleRate);
}

void watermark(double *buffer, int count, int channels)
{       
    double value[MAX_CHANNEL] = { 0.0, 0.0 };
    int i, j;

    if (channels > 1)
    {
        /*
        Sets j to be the first channel and while i is less than 1024/5, i += channels
        buffer[3] value is multiplied by 0, and set to 0
        this mutes that particular index value or frame
        this keeps going until i>=1024/5 and then the next channel is chosen where j = 2
        buffer[4] value is multiplied by 0 and set to 0
        this keeps going until i>=1024/5 where it calls back to the while loop in processFile
        */

        for (j = 0; j < channels; j++)
        {
            for (i = j; i < count / 5; i += channels)
            {
                buffer[i] *= value[j];
            }
        }
    }
    else
    {
        /*
        If audio file has 1 channel, buffer[i] is set to 0 for all values < 1024/5 frames
        and it goes back to normal until the next 1024 frames where the first  1024/5 frames.
        */
        for (i = 0; i < count / 5; i++)
        {
            buffer[i] *= value[0];
        }
    }

    return;
}

void printBuffer(double *buffer, size_t count)
{
    int i;

    for (i = 0; i < count; i++)
    {
        if (i != 0)
            printf("%d\n", buffer[i]);
    }
}

/*
- *DONE* - Need to create function that will read the newly outputted file 
- Find where the watermarks have been left on the audio
- Compare buffer[] values between original file and new outputted file
*/

最佳答案

while ((readCount = sf_read_double(infile, buffer, BUF_SIZE)))
{   

    watermark(buffer, readCount, info.channels);
    sf_write_double(outfile, buffer, readCount);
};

在这里,您一次又一次地使用缓冲区读取一些数据,对其添加水印并将其写出。只有完成后,您才会从缓冲区中打印最后剩余的数据:

for (i = 0; i < sizeof(buffer) / sizeof *buffer; i++)
{
    printBuffer(buffer, sizeof(buffer)/sizeof *buffer);
}

所以,与

#define MAX_CHANNEL 2
#define BUF_SIZE 1024

和一个 16 位 44100 立体声的波形文件,您只会看到最后 5.8 毫秒的声音数据,如果您有正常的音频(如音乐或一些几乎没有噪音的高质量录制语音),这可能几乎是静音。

另外:根据最后读取的 block ,您会看到文件的尾部,然后是尾部之前的某些部分,就像您看到最后 3.2 毫秒,然后是之前的 2.6 毫秒,这些部分在最后读取的调用。

/edit:好的,可能我弄错了数字,数据类型是 double 等等,但概念错误是相同的。

/edit 2:查看 Jonathan Leffler 的评论,我发现还有更多错误... - 我建议打开所有编译器警告,并尝试理解(并修复)它们。

关于c - 为什么我的数组在 C 中返回错误的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40706264/

相关文章:

python - 如何在Python中调用字典中的函数

c - 使用套接字发送和接收文件

c - XChangeProperty 对 32 位使用 long

c - 如何对 C 中的所有命令行参数求和?

javascript - react -Redux; .map 函数有时会重复数组

javascript - 在 Javascript 中的二维数组的数组中添加元素

javascript - 返回一个新数组,其中包含传递数组的第一个和最后一个元素

c++ - 将函数名称作为 C++ 类中另一个函数的参数传递

c++ - 我应该更改函数参数的值吗?

c - 使用 gcc 修改内存中的下一条指令