gpt4 book ai didi

Why is my DAW reading my sin wav as a square wav?(为什么我的DAW把我的sin-wav读成一个方形的wav?)

转载 作者:bug小助手 更新时间:2023-10-22 15:10:15 26 4
gpt4 key购买 nike



I am trying to generate a sin wave as PCM data in a wav file, but when I read the data into a DAW, it comes out as square.

我试图在wav文件中生成一个正弦波作为PCM数据,但当我将数据读取到DAW中时,它显示为方形。


I've confirmed that the data is in fact a sin wave using excel. I've tried switching to different sample rates and bit depths/amplitude, but the result is the same. The wav file comes out correctly written in format since the DAWs can read it, but it just has the incorrect sample data. Relevant code:

我已经用excel确认了这些数据实际上是一个正弦波。我试过切换到不同的采样率和比特深度/幅度,但结果是一样的。wav文件以正确的格式写入,因为DAW可以读取它,但它只是有不正确的样本数据。相关代码:


#define SAMPLE_RATE 48000.0
#define BIT_DEPTH 32
#define FREQUENCY 440.0 // A4
#define NUM_CHANNELS 1
#define AMPLITUDE 1.0

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

...
// header info

wav_header header =
{
{'R','I','F','F'},
36 + sampleCount * sizeof(float),
{'W','A','V','E'},
{'f','m','t',' '},
16,
1,
NUM_CHANNELS,
SAMPLE_RATE,
SAMPLE_RATE * NUM_CHANNELS * BIT_DEPTH / 8,
NUM_CHANNELS * BIT_DEPTH / 8,
BIT_DEPTH,
{'d','a','t','a'},
sampleCount * sizeof(float)
};

...

// Loop that writes the data. "generated" is the File
for (int i = 0; i < sampleCount; i++)
{
float t = (float)i / SAMPLE_RATE; // unit circle division
//float sample = (float)(AMPLITUDE * sin(2 * M_PI * FREQUENCY * t));
float x_sample = sinf(2 * M_PI * FREQUENCY * t);
fwrite(&x_sample, sizeof(float), 1, generated);
}


更多回答

Edit the question to provide a minimal reproducible example.

编辑问题以提供一个可重复的最小示例。

According to this: www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html your format code is wrong: 1 means PCM data, but it looks like you are writing floats - try to change it to 3 instead and see if that helps.

根据以下内容:www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html您的格式代码是错误的:1表示PCM数据,但看起来像是在写浮点-试着将其更改为3,看看这是否有帮助。

stackoverflow.com/questions/2062620/… plus Mcgil keeps a mirror of the original memo www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/…

stackoverflow.com/questions/2062620/…plus Mcgil保留了原始备忘录的镜像www.mmsp.ece.mgill.ca/Documents/AudioFormats/WAVE/Docs/…

优秀答案推荐

Let us be overly comprehensive about this. If you take at a look at some other wav implementations you will see a common thread of #define-ing wave formats from the RFC2361 June 1998 memo

让我们对此过于全面。如果你看看其他一些wav实现,你会看到RFC2361 1998年6月备忘录中的#defining wave格式的公共线程


To be different, let us use an enum. A guess of the wav_header struct has also been added.

为了与众不同,让我们使用枚举。还添加了对wav_header结构的猜测。


We are writing in a 32-bit floating point sample format so we need to use WAVE_FORMAT_IEEE_FLOAT, otherwise the assumption is that the file is written in a 32-bit signed integer format if you use audioFormat = 1 i.e. WAVE_FORMAT_PCM enum value.

我们是以32位浮点采样格式编写的,因此我们需要使用WAVE_format_IEE_FLOAT,否则,如果您使用audioFormat=1,即WAVE_format_PCM枚举值,则假设文件是以32位元带符号整数格式编写的。


#include <stdio.h>
#include <math.h>

#define SAMPLE_RATE 48000.0
#define BIT_DEPTH 32
#define FREQUENCY 440.0 // A4
#define NUM_CHANNELS 1
#define AMPLITUDE 1.0

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif


enum WAVE_FORMAT {
WAVE_FORMAT_UNKNOWN = 0x0000,
WAVE_FORMAT_PCM = 0x0001,
WAVE_FORMAT_ADPCM = 0x0002,
WAVE_FORMAT_IEEE_FLOAT = 0x0003,
WAVE_FORMAT_VSELP = 0x0004,
WAVE_FORMAT_IBM_CVSD = 0x0005,
WAVE_FORMAT_ALAW = 0x0006,
WAVE_FORMAT_MULAW = 0x0007,
WAVE_FORMAT_OKI_ADPCM = 0x0010,
WAVE_FORMAT_DVI_ADPCM = 0x0011,
WAVE_FORMAT_MEDIASPACE_ADPCM = 0x0012,
WAVE_FORMAT_SIERRA_ADPCM = 0x0013,
WAVE_FORMAT_G723_ADPCM = 0x0014,
WAVE_FORMAT_DIGISTD = 0x0015,
WAVE_FORMAT_DIGIFIX = 0x0016,
WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017,
WAVE_FORMAT_MEDIAVISION_ADPCM = 0x0018,
WAVE_FORMAT_CU_CODEC = 0x0019,
WAVE_FORMAT_YAMAHA_ADPCM = 0x0020,
WAVE_FORMAT_SONARC = 0x0021,
WAVE_FORMAT_DSPGROUP_TRUESPEECH = 0x0022,
WAVE_FORMAT_ECHOSC1 = 0x0023,
WAVE_FORMAT_AUDIOFILE_AF36 = 0x0024,
WAVE_FORMAT_APTX = 0x0025,
WAVE_FORMAT_AUDIOFILE_AF10 = 0x0026,
WAVE_FORMAT_PROSODY_1612 = 0x0027,
WAVE_FORMAT_LRC = 0x0028,
WAVE_FORMAT_DOLBY_AC2 = 0x0030,
WAVE_FORMAT_GSM610 = 0x0031,
WAVE_FORMAT_MSNAUDIO = 0x0032,
WAVE_FORMAT_ANTEX_ADPCME = 0x0033,
WAVE_FORMAT_CONTROL_RES_VQLPC = 0x0034,
WAVE_FORMAT_DIGIREAL = 0x0035,
WAVE_FORMAT_DIGIADPCM = 0x0036,
WAVE_FORMAT_CONTROL_RES_CR10 = 0x0037,
WAVE_FORMAT_NMS_VBXADPCM = 0x0038,
WAVE_FORMAT_ROLAND_RDAC = 0x0039,
WAVE_FORMAT_ECHOSC3 = 0x003A,
WAVE_FORMAT_ROCKWELL_ADPCM = 0x003B,
WAVE_FORMAT_ROCKWELL_DIGITALK = 0x003C,
WAVE_FORMAT_XEBEC = 0x003D,
WAVE_FORMAT_G721_ADPCM = 0x0040,
WAVE_FORMAT_G728_CELP = 0x0041,
WAVE_FORMAT_MSG723 = 0x0042,
WAVE_FORMAT_MPEG = 0x0050,
WAVE_FORMAT_RT24 = 0x0052,
WAVE_FORMAT_PAC = 0x0053,
WAVE_FORMAT_MPEGLAYER3 = 0x0055,
WAVE_FORMAT_LUCENT_G723 = 0x0059,
WAVE_FORMAT_CIRRUS = 0x0060,
WAVE_FORMAT_ESPCM = 0x0061,
WAVE_FORMAT_VOXWARE = 0x0062,
WAVE_FORMAT_CANOPUS_ATRAC = 0x0063,
WAVE_FORMAT_G726_ADPCM = 0x0064,
WAVE_FORMAT_G722_ADPCM = 0x0065,
WAVE_FORMAT_DSAT = 0x0066,
WAVE_FORMAT_DSAT_DISPLAY = 0x0067,
WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 0x0069,
WAVE_FORMAT_VOXWARE_AC8 = 0x0070,
WAVE_FORMAT_VOXWARE_AC10 = 0x0071,
WAVE_FORMAT_VOXWARE_AC16 = 0x0072,
WAVE_FORMAT_VOXWARE_AC20 = 0x0073,
WAVE_FORMAT_VOXWARE_RT24 = 0x0074,
WAVE_FORMAT_VOXWARE_RT29 = 0x0075,
WAVE_FORMAT_VOXWARE_RT29HW = 0x0076,
WAVE_FORMAT_VOXWARE_VR12 = 0x0077,
WAVE_FORMAT_VOXWARE_VR18 = 0x0078,
WAVE_FORMAT_VOXWARE_TQ40 = 0x0079,
WAVE_FORMAT_SOFTSOUND = 0x0080,
WAVE_FORMAT_VOXWARE_TQ60 = 0x0081,
WAVE_FORMAT_MSRT24 = 0x0082,
WAVE_FORMAT_G729A = 0x0083,
WAVE_FORMAT_MVI_MV12 = 0x0084,
WAVE_FORMAT_DF_G726 = 0x0085,
WAVE_FORMAT_DF_GSM610 = 0x0086,
//WAVE_FORMAT_ISIAUDIO = 0x0088, // duplicate of 0x1401
WAVE_FORMAT_ONLIVE = 0x0089,
WAVE_FORMAT_SBC24 = 0x0091,
WAVE_FORMAT_DOLBY_AC3_SPDIF = 0x0092,
WAVE_FORMAT_ZYXEL_ADPCM = 0x0097,
WAVE_FORMAT_PHILIPS_LPCBB = 0x0098,
WAVE_FORMAT_PACKED = 0x0099,
WAVE_FORMAT_RHETOREX_ADPCM = 0x0100,
WAVE_FORMAT_IRAT = 0x0101,
WAVE_FORMAT_VIVO_G723 = 0x0111,
WAVE_FORMAT_VIVO_SIREN = 0x0112,
WAVE_FORMAT_DIGITAL_G723 = 0x0123,
WAVE_FORMAT_CREATIVE_ADPCM = 0x0200,
WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 0x0202,
WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 0x0203,
WAVE_FORMAT_QUARTERDECK = 0x0220,
WAVE_FORMAT_FM_TOWNS_SND = 0x0300,
WAVE_FORMAT_BTV_DIGITAL = 0x0400,
WAVE_FORMAT_VME_VMPCM = 0x0680,
WAVE_FORMAT_OLIGSM = 0x1000,
WAVE_FORMAT_OLIADPCM = 0x1001,
WAVE_FORMAT_OLICELP = 0x1002,
WAVE_FORMAT_OLISBC = 0x1003,
WAVE_FORMAT_OLIOPR = 0x1004,
WAVE_FORMAT_LH_CODEC = 0x1100,
WAVE_FORMAT_NORRIS = 0x1400,
WAVE_FORMAT_ISIAUDIO = 0x1401,
WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = 0x1500,
WAVE_FORMAT_DVM = 0x2000,
};


typedef struct wav_header_t
{
/// The first 4 byte of a wav file should be the characters "RIFF" */
char chunkID[4];
/// 36 + SubChunk2Size
uint32_t chunkSize; // You Don't know this until you write your data but at a minimum it is 36 for an empty file
/// "should be characters "WAVE"
char format[4];
/// " This should be the letters "fmt ", note the space character
char subChunk1ID[4];
///: 0x10 as audioFormat is uint16_t
uint32_t subChunk1Size;
///: For PCM this is 1, other values check http://www.ietf.org/rfc/rfc2361.txt or use WAVE_FORMAT enum above
uint16_t audioFormat;
///: Mono = 1, Stereo = 2, etc.
uint16_t numChannels;
///: Sample Rate of file
uint32_t sampleRate;
///: SampleRate * NumChannels * BitsPerSample/8
uint32_t byteRate;
///: The number of byte for one frame NumChannels * BitsPerSample/8
uint16_t blockAlign;
///: 8 bits = 8, 16 bits = 16
uint16_t bitsPerSample;
///: Contains the letters "data"
char subChunk2ID[4];
///: == NumSamples * NumChannels * BitsPerSample/8 i.e. number of byte in the data.
uint32_t subChunk2Size; // You don't know this until you have your audio data
}wav_header;

int main(int argc, const char * argv[])
{
uint32_t sampleCount = 44100;

wav_header header =
{
{'R','I','F','F'},
36 + sampleCount * sizeof(float),
{'W','A','V','E'},
{'f','m','t',' '},
16,
(uint16_t)WAVE_FORMAT_IEEE_FLOAT,
NUM_CHANNELS,
SAMPLE_RATE,
SAMPLE_RATE * NUM_CHANNELS * BIT_DEPTH / 8,
NUM_CHANNELS * BIT_DEPTH / 8,
BIT_DEPTH,
{'d','a','t','a'},
sampleCount * sizeof(float)
};

FILE *generated = fopen("file.wav", "wb");

fwrite(&header, sizeof(wav_header), 1, generated);

// Loop that writes the data. "generated" is the File
for (int i = 0; i < sampleCount; i++)
{
float t = (float)(i) / SAMPLE_RATE; // unit circle division

// set max amplitude to -3dBFS
float x_sample = 0.707f * sinf(2.0f * M_PI * FREQUENCY * t);

fwrite(&x_sample, sizeof(float), 1, generated);
}

fclose(generated);

return 0;
}

There are other potential problems such as the manner that sine wave is generated is limited by floating point accuracy. It would like stop generating a tone after ~6 minutes. Also, it is good practice to limit the max amplitude to below 0 dBFS. Comprehensive answer on both of those topics are reasonably outside the scope of the question.

还有其他潜在的问题,例如正弦波的产生方式受到浮点精度的限制。它希望在大约6分钟后停止生成音调。此外,将最大振幅限制在0dBFS以下也是一种良好的做法。对这两个问题的综合回答在合理的范围之外。



Try generating a tone using the C89 WAV library.

尝试使用C89 WAV库生成音调。


https://github.com/jocic/c89-wav

https://github.com/jocic/c89-wav


uint32_t i;
float j;

///////////////////////

uint32_t sample_rate = 44100;
uint32_t duration = 2;
uint32_t total_samples = sample_rate * duration;

///////////////////////

WAV_FILE file;
WAV_PCM16 sample;

///////////////////////

file = wav_open("test.wav", WAV_NEW);

wav_set_defaults(&file, 1);

for (i = 0, j = 0; i < total_samples; i++, j+=0.1F) {
sample = sin(j) * WAV_PCM16_MAX;
wav_push_sample(&file, &sample, NULL);
}

wav_close(&file);

For more advanced stuff, here are the examples.

对于更高级的东西,以下是示例。


https://github.com/jocic/c89-wav/tree/main/examples

https://github.com/jocic/c89-wav/tree/main/examples


更多回答

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