gpt4 book ai didi

c++ - 我如何运行以下代码

转载 作者:行者123 更新时间:2023-11-28 05:55:58 26 4
gpt4 key购买 nike

我有一个相对较大的 C++ 项目,我正在尝试弄清楚如何运行它。有如下所述的 3 个代码文件和 2 个 .wav 音频文件 - test.wav 和 poolIR.wav。

该程序应该将测试文件与脉冲响应进行卷积并生成第三个输出文件。这 2 个音频文件必须在运行时传递给程序,我是 C/C++ 的新手,所以我想看看我应该怎么做。谁能帮帮我。下面是代码。

我使用的是 WINDOWS 7 并且安装了 gcc。

卷积.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fstream>
#include <iostream>
#include <math.h>
#include "CWav.h"

using namespace std;

#define DEBUG_MODE

/* Test tone frequency in Hz */
#define FREQUENCY 440.0

/* Test tone duration in seconds */
#define DURATION 2.0

/* Standard sample rate in Hz */
#define SAMPLE_RATE 44100.0

/* Standard sample size in bits */
#define BITS_PER_SAMPLE 16

/* Standard sample size in bytes */
#define BYTES_PER_SAMPLE (BITS_PER_SAMPLE/8)

/* Number of channels */
#define MONOPHONIC 1
#define STEREOPHONIC 2

#define SIZE 8
#define PI 3.141592653589793
#define TWO_PI (2.0 * PI)
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr


void outputToFile(double data[], CWav* original , int numberOfSamples, char* outputFile);
void four1(double data[], int nn, int isign);
void writeWaveFileHeader(int channels, int numberSamples, int bitsPerSample, double sampleRate, FILE *outputFile);
size_t fwriteIntLSB(int data, FILE *stream);
void getSignal(CWav *input, double x[]);
size_t fwriteShortLSB(short int data, FILE *stream);
void outputToFile(double data[], CWav* original , int numberOfSamples, char* outputFile);


// The four1 FFT from Numerical Recipes in C,
// p. 507 - 508.
// Note: changed float data types to double.
// nn must be a power of 2, and use +1 for
// isign for an FFT, and -1 for the Inverse FFT.
// The data is complex, so the array size must be
// nn*2. This code assumes the array starts
// at index 1, not 0, so subtract 1 when
// calling the routine (see main() below).

void four1(double data[], int nn, int isign)
{
unsigned long n, mmax, m, j, istep, i;
double wtemp, wr, wpr, wpi, wi, theta;
double tempr, tempi;

n = nn << 1;
j = 1;

for (i = 1; i < n; i += 2) {
if (j > i) {
SWAP(data[j], data[i]);
SWAP(data[j+1], data[i+1]);
}
m = nn;
while (m >= 2 && j > m) {
j -= m;
m >>= 1;
}
j += m;
}

mmax = 2;
while (n > mmax) {
istep = mmax << 1;
theta = isign * (6.28318530717959 / mmax);
wtemp = sin(0.5 * theta);
wpr = -2.0 * wtemp * wtemp;
wpi = sin(theta);
wr = 1.0;
wi = 0.0;
for (m = 1; m < mmax; m += 2) {
for (i = m; i <= n; i += istep) {
j = i + mmax;
tempr = wr * data[j] - wi * data[j+1];
tempi = wr * data[j+1] + wi * data[j];
data[j] = data[i] - tempr;
data[j+1] = data[i+1] - tempi;
data[i] += tempr;
data[i+1] += tempi;
}
wr = (wtemp = wr) * wpr - wi * wpi + wr;
wi = wi * wpr + wtemp * wpi + wi;
}
mmax = istep;
}
}

void writeWaveFileHeader(int channels, int numberSamples, int bitsPerSample,
double sampleRate, FILE *outputFile)
{
/* Calculate the total number of bytes for the data chunk */
int dataChunkSize = channels * numberSamples * (bitsPerSample / 8);

/* Calculate the total number of bytes for the form size */
int formSize = 36 + dataChunkSize;

/* Calculate the total number of bytes per frame */
short int frameSize = channels * (bitsPerSample / 8);

/* Calculate the byte rate */
int bytesPerSecond = (int)ceil(sampleRate * frameSize);

/* Write header to file */
/* Form container identifier */
fputs("RIFF", outputFile);

/* Form size */
fwriteIntLSB(formSize, outputFile);

/* Form container type */
fputs("WAVE", outputFile);

/* Format chunk identifier (Note: space after 't' needed) */
fputs("fmt ", outputFile);

/* Format chunk size (fixed at 16 bytes) */
fwriteIntLSB(16, outputFile);

/* Compression code: 1 = PCM */
fwriteShortLSB(1, outputFile);

/* Number of channels */
fwriteShortLSB((short)channels, outputFile);

/* Output Sample Rate */
fwriteIntLSB((int)sampleRate, outputFile);

/* Bytes per second */
fwriteIntLSB(bytesPerSecond, outputFile);

/* Block alignment (frame size) */
fwriteShortLSB(frameSize, outputFile);

/* Bits per sample */
fwriteShortLSB(bitsPerSample, outputFile);

/* Sound Data chunk identifier */
fputs("data", outputFile);

/* Chunk size */
fwriteIntLSB(dataChunkSize, outputFile);
}



/******************************************************************************
*
* function: fwriteIntLSB
*
* purpose: Writes a 4-byte integer to the file stream, starting
* with the least significant byte (i.e. writes the int
* in little-endian form). This routine will work on both
* big-endian and little-endian architectures.
*
* internal
* functions: none
*
* library
* functions: fwrite
*
******************************************************************************/

size_t fwriteIntLSB(int data, FILE *stream)
{
unsigned char array[4];

array[3] = (unsigned char)((data >> 24) & 0xFF);
array[2] = (unsigned char)((data >> 16) & 0xFF);
array[1] = (unsigned char)((data >> 8) & 0xFF);
array[0] = (unsigned char)(data & 0xFF);
return fwrite(array, sizeof(unsigned char), 4, stream);
}



/******************************************************************************
*
* function: fwriteShortLSB
*
* purpose: Writes a 2-byte integer to the file stream, starting
* with the least significant byte (i.e. writes the int
* in little-endian form). This routine will work on both
* big-endian and little-endian architectures.
*
* internal
* functions: none
*
* library
* functions: fwrite
*
******************************************************************************/

size_t fwriteShortLSB(short int data, FILE *stream)
{
unsigned char array[2];

array[1] = (unsigned char)((data >> 8) & 0xFF);
array[0] = (unsigned char)(data & 0xFF);
return fwrite(array, sizeof(unsigned char), 2, stream);
}

void getSignal(CWav *input, double x[]) {
for ( int i = 0; i < input->mySignalSize; i++ )
x[i] = ((double)input->my_signal[i])/32678.0;
}

void outputToFile(double output_signal[], CWav* original , int numberOfSamples, char* outputFile) {

/* Open a binary output file stream for writing */
FILE *outputFileStream = fopen(outputFile, "wb");

/* Write the WAVE file header */
writeWaveFileHeader(original->myChannels, numberOfSamples, original->myBitsPerSample,
original->mySampleRate, outputFileStream);

int i;
float maxValInResult = -1.0;
for (i = 0; i < numberOfSamples; i++ )
if ( output_signal[i] > maxValInResult )
maxValInResult = output_signal[i];

float maxValInInput = -1.0;
for (i = 0; i < numberOfSamples; i++ )
if (original->my_signal[i] > maxValInInput )
maxValInInput = original->my_signal[i];

for (i = 0; i < numberOfSamples; i++ )
fwriteShortLSB((short)(output_signal[i] / maxValInResult * maxValInInput), outputFileStream);


/* Close the output file stream */
fclose(outputFileStream);
}
//convolve inputfile IRfile outputfile as inputs to main
int main(int argc, char* argv[])
{
if (argc != 4) {
cout << "USAGE: ./convolve inputfile IRfile outputfile" << endl;
//system("PAUSE");
return 0;
}
cout << argv[0] << endl;
cout << "Input File:" << argv[1] << endl;
cout << "IRfile:" << argv[2] << endl;
cout << "outputfile File:" <<argv[3] << endl;


char *outputFilename = argv[3];

/* Create the sine wave test tone, using the specified
frequency, duration, and number of channels, writing to
a .wav file with the specified output filename */

//createTestTone(FREQUENCY, DURATION, MONOPHONIC, BITS_PER_SAMPLE, SAMPLE_RATE, outputFilename);

CWav *inputSignal = new CWav();
inputSignal->readInput(argv[1]);

//manipulate(inputSignal, 2);

CWav *impulse = new CWav();
impulse->readInput(argv[2]);

cout << "Input Signal: " << inputSignal->mySignalSize << ", Impulse Size: " << impulse->mySignalSize << endl;

double h[impulse->mySignalSize];
double x[inputSignal->mySignalSize];

getSignal(impulse, h);
getSignal(inputSignal, x);


int sizeH = impulse->mySignalSize;
int sizeX = inputSignal->mySignalSize;

cout << "SIZES(H,X)" << endl;
cout << sizeH << endl;
cout << sizeX << endl;

int maxSize = 0;
if(sizeX >= sizeH) {
maxSize = sizeX;
}
else {
maxSize = sizeH;
}
cout << "maxSize: " << maxSize << endl;

int power = 0;
int pow2 = 0;

pow2 = (int) log2(maxSize) + 1;
pow2 = pow(2,pow2);

cout << "POW :" << pow2 << endl;

int i = 0;

int doublePow2 = 2 * pow2;
//set hComplex with 0's
double hComplex[doublePow2];
double *xComplex = new double[doublePow2];
//set hComplex , xComplex with 0's
for(i = 0; i < doublePow2; i++) {
hComplex[i] = 0.0;
xComplex[i] = 0.0;
}

//padding the complex number with 0 and the real number with original value for h
for(i = 0; i < sizeH; i++) {
hComplex[2*i] = h[i];
}

//padding the complex number with 0 and the real number with original value for x
for(i = 0; i < sizeX; i++) {
xComplex[2*i] = x[i];
}


four1(hComplex, pow2, 1);
four1(xComplex, pow2, 1);

double *yComplex = new double[doublePow2];
for(i = 0; i < pow2 ; i++) {
yComplex[i*2] = xComplex[i] * hComplex[i] - xComplex[i+1] * hComplex[i+1];
yComplex[i*2+1] = xComplex[i+1] * hComplex[i] + xComplex[i] * hComplex[i+1];
}

four1(yComplex-1, pow2, -1);
outputToFile(yComplex, inputSignal, pow2, outputFilename);
}

CWav.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fstream>
#include <iostream>

#include "CWav.h"

using namespace std;

void CWav::readInput(char *filename)
{

ifstream inFile( filename, ios::in | ios::binary);

//printf("Reading wav file...\n"); // for debugging only

inFile.seekg(4, ios::beg);
inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize

inFile.seekg(16, ios::beg);
inFile.read( (char*) &mySubChunk1Size, 4 ); // read the SubChunk1Size

inFile.seekg(20, ios::beg);
inFile.read( (char*) &myFormat, sizeof(short) ); // read the file format. This should be 1 for PCM

//inFile.seekg(22, ios::beg);
inFile.read( (char*) &myChannels, sizeof(short) ); // read the # of channels (1 or 2)

//inFile.seekg(24, ios::beg);
inFile.read( (char*) &mySampleRate, sizeof(int) ); // read the samplerate

//inFile.seekg(28, ios::beg);
inFile.read( (char*) &myByteRate, sizeof(int) ); // read the byterate

//inFile.seekg(32, ios::beg);
inFile.read( (char*) &myBlockAlign, sizeof(short) ); // read the blockalign

//inFile.seekg(34, ios::beg);
inFile.read( (char*) &myBitsPerSample, sizeof(short) ); // read the bitspersample

inFile.seekg(40, ios::beg);
inFile.read( (char*) &myDataSize, sizeof(int) ); // read the size of the data


// read the data chunk
myData = new char[myDataSize];
inFile.seekg(44, ios::beg);
inFile.read(myData, myDataSize);

inFile.close(); // close the input file

my_signal = NULL;

if ( myBitsPerSample == 8 )
{
mySignalSize = myDataSize;
my_signal = new short[mySignalSize];
for ( int i = 0; i < myDataSize; i++ )
my_signal[i] = (short)( (unsigned char) myData[i] );

}
else if ( myBitsPerSample == 16 ){
mySignalSize = myDataSize / 2;
my_signal = new short[mySignalSize];
short val;
for ( int i = 0; i < myDataSize; i+=2 )
{
val = (short)( (unsigned char) myData[i] );
val += (short)( (unsigned char) myData[i+1] ) * 256;
my_signal[i/2] = val;
}
}
}

CWav.h:

#ifndef CWavH
#define CWavH

class CWav
{
private:
char* myData;
public:
int myChunkSize;
int mySubChunk1Size;
short myFormat;
short myChannels;
int mySampleRate;
int myByteRate;
short myBlockAlign;
short myBitsPerSample;
int myDataSize;

short *my_signal;
int mySignalSize;

public:

void readInput(char *filename);

};

#endif

然后我有 2 个音频文件。poolIR.wav 和 test.wav

最佳答案

C++ 不是脚本语言,你必须先编译它。

要使用 gcc 编译代码,请尝试以下操作(假设所有文件都在同一个目录下):

g++ convolve.cpp CWav.cpp -o convolve.exe

这应该会生成一个名为 convolve.exe 的可执行文件。

-o 标志指定输出文件名 (convolve.exe)。查看gcc documentation了解详情。

关于c++ - 我如何运行以下代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34150714/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com