简体   繁体   English

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

[英]Why is my array returning the wrong values in C?

I'm trying to use the libsndfile library to read/write information between audio files. 我正在尝试使用libsndfile库在音频文件之间读取/写入信息。

I've managed to read the original file, write a copy of it with "watermark" values. 我设法读取了原始文件,并使用“水印”值编写了一个副本。

All I'm trying to do now is print any index where the value is not 0. 我现在想要做的就是打印任何值不为0的索引。

However, when I call my printBuffer() function, it's returning all 0s even though when on debug mode, I can see that the values in buffer are not zero/changing each iteration. 但是,当我调用我的printBuffer()函数时,即使在调试模式下,它也会返回全0,我可以看到缓冲区中的值不为零/每次迭代都更改。

Am I calling the buffer array incorrectly? 我是否错误地调用了缓冲区数组?

I'm still new to C so if you have any suggestions they would be greatly appreciated. 我对C还是很陌生,因此,如果您有任何建议,将不胜感激。

Thank you. 谢谢。

Code: 码:

#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);
};

Here, you use the buffer again and again to read some data, watermark it and write it out.Only once you are done, you print the last remaining data out of the buffer: 在这里,您一次又一次地使用缓冲区读取一些数据,对其加水印并将其写出。只有完成后,才从缓冲区中打印出最后剩余的数据:

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

So, with 因此,

#define MAX_CHANNEL 2
#define BUF_SIZE 1024

and a wave file with 16 bit 44100 stereo, you will only see the last 5.8ms of sound data, which probably is almost silence, if you have normal audio like music or some high quality recorded voice with almost no noise. 以及具有16位44100立体声的wave文件,如果您具有正常的音频(例如音乐)或一些高质量的录制语音而几乎没有噪声,则您只会看到最后5.8ms的声音数据,这几乎是无声的。

Additionally: Depending on the last block read, you see the tail of the file, and then some part prior to the tail, like you see the last 3.2ms and then the 2.6ms prior to that, which was not overwritten in the last read call. 另外:根据最后读取的块,您会看到文件的尾部,然后看到尾部之前的某部分,就像您看到的最后3.2ms然后是其之前的2.6ms,这在上次读取时并未覆盖呼叫。

/edit: Ok, probably I got the numbers wrong, data type is double and so on, but the conceptual error is the same. / edit:好的,可能我输入的数字错误,数据类型为double,依此类推,但是概念上的错误是相同的。

/edit 2: Looking at Jonathan Leffler's comment, I see there are even more errors ... - I recommend switching on ALL compiler warnings, and try to understand (and fix) them. / edit 2:查看乔纳森·莱弗勒(Jonathan Leffler)的评论,我发现还有更多错误...-我建议打开所有编译器警告,并尝试理解(并修复)它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM