如何在 C 中使用 'fwrite'?
How to use 'fwrite' in C?
我正在尝试使用 'fwrite' 并制作 snd 文件。
我想制作 IIR 滤波器。我制作了一个 FIR 滤波器,并将代码用于 IIR 滤波器。
(当然,改变coeffs)
但我认为 'fwrite' 不起作用。因为 IIR 滤波器的结果仅为零。
我想我在我的代码中犯了一些错误。
你能给我一个提示吗?我现在完全处于恐慌之中。
当我检查输出[] 时,它看起来很好。正如我所尊重的,它有一组整数。
不知道怎么写
我知道代码很长,看起来很难。
但是我不知道所以如果你帮我一把,我会很高兴。
感谢阅读。
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
// Filter Code Definitions
#define MAX_INPUT_LEN 80
#define MAX_FLT_LEN 14
#define BUFFER_LEN (MAX_FLT_LEN - 1 + MAX_INPUT_LEN)
double insamp[BUFFER_LEN];
// IIR inititialization
void IirFloatInit(void)
{
memset(insamp, 0, sizeof(insamp));
}
// the IIR filter function
void IirFloat(double *coeffs, double *input, double *output, int length, int
filterLength)
{
double acc;
double *coeffp;
double *inputp;
int n;
int k;
// put the new samples at the high end of the buffer
memcpy(&insamp[filterLength - 1], input, length * sizeof(double));
for (n = 0; n < length; n++) {
coeffp = coeffs;
inputp = &insamp[filterLength - 1 + n];
acc = 0;
for (k = 0; k < filterLength; k++) {
acc += (*coeffp++) * (*inputp--);
}
output[n] = acc;
}
memmove(&insamp[0], &insamp[length], (filterLength - 1) * sizeof(double));
}
double coeffs[MAX_FLT_LEN];
void intToFloat(int16_t *input, double *output, int length)
{
int i;
for (i = 0; i < length; i++) {
output[i] = (double)input[i];
}
}
void floatToInt(double *input, int16_t *output, int length)
{
int i;
for (i = 0; i < length; i++)
{
input[i] += 0.5;
if (input[i] > 32767.0)
{
input[i] = 32767.0;
}
else if (input[i] < -32768.0)
{
input[i] = -32768.0;
}
output[i] = (int16_t)input[i];
}
}
// number of samples to read per loop
int main(void)
{
int size;
int16_t input[MAX_INPUT_LEN];
int16_t output[MAX_INPUT_LEN];
double floatInput[MAX_INPUT_LEN];
double floatOutput[MAX_INPUT_LEN];
double coeffs[MAX_FLT_LEN];
FILE *in_fid;
FILE *out_fid;
FILE *filter;
// open the input waveform file
in_fid = fopen("input.snd", "rb");
if (in_fid == 0) {
printf("couldn't open input.snd");
return;
}
// open the output waveform file
out_fid = fopen("outputFloatIIR.snd", "wb");
if (out_fid == 0) {
printf("couldn't open outputFloat.snd");
return;
}
filter = fopen("coeffs_iir.txt", "r");
if (filter == NULL) {
puts("couldn't open coeffs_iir.txt");
return;
}
for (int i = 0; i < MAX_FLT_LEN; i++) {
fscanf(filter, "%le", &coeffs[i]);
printf("%le \n", coeffs[i]);
}
IirFloatInit();
do {
size = fread(input, sizeof(int16_t), MAX_INPUT_LEN, in_fid);
intToFloat(input, floatInput, size);
IirFloat(coeffs, floatInput, floatOutput, size, MAX_FLT_LEN);
floatToInt(floatOutput, output, size);
fwrite(output, sizeof(int16_t), size, out_fid);
} while (size != 0);
fclose(in_fid);
fclose(out_fid);
fclose(filter);
getchar();
return 0;
}
进入手册(man printf)我可以读到这个:
eE The double argument is rounded and converted in the style [-]d.ddde+-dd where there is one digit before the decimal-point
character and the number of digits after it is equal to the precision;
if the
precision is missing, it is taken as 6; if the precision is zero, no decimal-point character appears. An E conversion uses the
letter E' (rather than
e') to introduce the exponent. The exponent
always contains at least two digits; if the value is zero, the exponent is 00.
你存储系数的文件是那种格式的?如果您使用调试器,读入 fscanf 的值会怎样?
我的意思是,可能格式不是预期的,因此你得到 0。也许你想使用 fscanf(filter, "%lf", &coeffs[i]);
?
fscanf 返回的值是多少?进入手册(man fscanf)可以看到这个:
RETURN VALUES
These functions return the number of input items assigned. This can be fewer than provided for, or even zero, in the event of a
matching failure. Zero indicates that, although there was input
available, no
conversions were assigned; typically this is due to an invalid input character, such as an alphabetic character for a `%d'
conversion. The value EOF is returned if an input failure occurs
before any conver-
sion such as an end-of-file occurs. If an error or end-of-file occurs after conversion has begun, the number of conversions which
were successfully completed is returned.
我正在尝试使用 'fwrite' 并制作 snd 文件。 我想制作 IIR 滤波器。我制作了一个 FIR 滤波器,并将代码用于 IIR 滤波器。 (当然,改变coeffs) 但我认为 'fwrite' 不起作用。因为 IIR 滤波器的结果仅为零。 我想我在我的代码中犯了一些错误。
你能给我一个提示吗?我现在完全处于恐慌之中。
当我检查输出[] 时,它看起来很好。正如我所尊重的,它有一组整数。
不知道怎么写
我知道代码很长,看起来很难。
但是我不知道所以如果你帮我一把,我会很高兴。 感谢阅读。
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
// Filter Code Definitions
#define MAX_INPUT_LEN 80
#define MAX_FLT_LEN 14
#define BUFFER_LEN (MAX_FLT_LEN - 1 + MAX_INPUT_LEN)
double insamp[BUFFER_LEN];
// IIR inititialization
void IirFloatInit(void)
{
memset(insamp, 0, sizeof(insamp));
}
// the IIR filter function
void IirFloat(double *coeffs, double *input, double *output, int length, int
filterLength)
{
double acc;
double *coeffp;
double *inputp;
int n;
int k;
// put the new samples at the high end of the buffer
memcpy(&insamp[filterLength - 1], input, length * sizeof(double));
for (n = 0; n < length; n++) {
coeffp = coeffs;
inputp = &insamp[filterLength - 1 + n];
acc = 0;
for (k = 0; k < filterLength; k++) {
acc += (*coeffp++) * (*inputp--);
}
output[n] = acc;
}
memmove(&insamp[0], &insamp[length], (filterLength - 1) * sizeof(double));
}
double coeffs[MAX_FLT_LEN];
void intToFloat(int16_t *input, double *output, int length)
{
int i;
for (i = 0; i < length; i++) {
output[i] = (double)input[i];
}
}
void floatToInt(double *input, int16_t *output, int length)
{
int i;
for (i = 0; i < length; i++)
{
input[i] += 0.5;
if (input[i] > 32767.0)
{
input[i] = 32767.0;
}
else if (input[i] < -32768.0)
{
input[i] = -32768.0;
}
output[i] = (int16_t)input[i];
}
}
// number of samples to read per loop
int main(void)
{
int size;
int16_t input[MAX_INPUT_LEN];
int16_t output[MAX_INPUT_LEN];
double floatInput[MAX_INPUT_LEN];
double floatOutput[MAX_INPUT_LEN];
double coeffs[MAX_FLT_LEN];
FILE *in_fid;
FILE *out_fid;
FILE *filter;
// open the input waveform file
in_fid = fopen("input.snd", "rb");
if (in_fid == 0) {
printf("couldn't open input.snd");
return;
}
// open the output waveform file
out_fid = fopen("outputFloatIIR.snd", "wb");
if (out_fid == 0) {
printf("couldn't open outputFloat.snd");
return;
}
filter = fopen("coeffs_iir.txt", "r");
if (filter == NULL) {
puts("couldn't open coeffs_iir.txt");
return;
}
for (int i = 0; i < MAX_FLT_LEN; i++) {
fscanf(filter, "%le", &coeffs[i]);
printf("%le \n", coeffs[i]);
}
IirFloatInit();
do {
size = fread(input, sizeof(int16_t), MAX_INPUT_LEN, in_fid);
intToFloat(input, floatInput, size);
IirFloat(coeffs, floatInput, floatOutput, size, MAX_FLT_LEN);
floatToInt(floatOutput, output, size);
fwrite(output, sizeof(int16_t), size, out_fid);
} while (size != 0);
fclose(in_fid);
fclose(out_fid);
fclose(filter);
getchar();
return 0;
}
进入手册(man printf)我可以读到这个:
eE The double argument is rounded and converted in the style [-]d.ddde+-dd where there is one digit before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero, no decimal-point character appears. An E conversion uses the letter
E' (rather than
e') to introduce the exponent. The exponent always contains at least two digits; if the value is zero, the exponent is 00.
你存储系数的文件是那种格式的?如果您使用调试器,读入 fscanf 的值会怎样?
我的意思是,可能格式不是预期的,因此你得到 0。也许你想使用 fscanf(filter, "%lf", &coeffs[i]);
?
fscanf 返回的值是多少?进入手册(man fscanf)可以看到这个:
RETURN VALUES These functions return the number of input items assigned. This can be fewer than provided for, or even zero, in the event of a matching failure. Zero indicates that, although there was input available, no conversions were assigned; typically this is due to an invalid input character, such as an alphabetic character for a `%d' conversion. The value EOF is returned if an input failure occurs before any conver- sion such as an end-of-file occurs. If an error or end-of-file occurs after conversion has begun, the number of conversions which were successfully completed is returned.