- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一些使用 PortAudio library 捕获音频的代码, 然后尝试将其打包到 WAV codec 中.然后我尝试将该文件转换为 FLAC file codec ,但它一直告诉我它不是有效的 .wav
文件。
wav.h
:
#include <stdint.h>
#include <string.h>
/**
* @struct WaveHeader
* @brief A basic WAVE header
*/
typedef struct
{
char RIFF_marker[4];
uint32_t file_size;
char filetype_header[4];
char format_marker[4];
uint32_t data_header_length;
uint16_t format_type;
uint16_t number_of_channels;
uint32_t sample_rate;
uint32_t bytes_per_second;
uint16_t bytes_per_frame;
uint16_t bits_per_sample;
} WaveHeader;
WaveHeader *genericWAVHeader(uint32_t sample_rate, uint16_t bit_depth, uint16_t channels);
WaveHeader *retrieveWAVHeader(const void *ptr);
int writeWAVHeader(FILE* fd, WaveHeader *hdr);
int recordWAV(const char *fileName, WaveHeader *hdr, uint32_t duration);
capture.c
:
#include <stdio.h>
#include <stdlib.h>
#include <portaudio.h>
#include <unistd.h>
#include <math.h>
#include "wav.h"
typedef struct
{
int frameIndex; /* Index into sample array. */
int maxFrameIndex;
char* recordedSamples;
} PAData;
WaveHeader *genericWAVHeader(uint32_t sample_rate, uint16_t bit_depth, uint16_t channels)
{
WaveHeader *hdr = malloc(sizeof(*hdr));
if (!hdr) return NULL;
memcpy(&hdr->RIFF_marker, "RIFF", 4);
memcpy(&hdr->filetype_header, "WAVE", 4);
memcpy(&hdr->format_marker, "fmt ", 4);
hdr->data_header_length = 16;
hdr->format_type = 1;
hdr->number_of_channels = channels;
hdr->sample_rate = sample_rate;
hdr->bytes_per_second = sample_rate * channels * bit_depth / 8;
hdr->bytes_per_frame = channels * bit_depth / 8;
hdr->bits_per_sample = bit_depth;
return hdr;
}
int writeWAVHeader(FILE* fd, WaveHeader *hdr)
{
if (!hdr) return -1;
fwrite(&hdr->RIFF_marker, sizeof(*hdr->RIFF_marker), sizeof(&hdr->RIFF_marker), fd);
fwrite(&hdr->file_size, sizeof(hdr->file_size), sizeof(&hdr->file_size), fd);
fwrite(&hdr->filetype_header, sizeof(*hdr->filetype_header), sizeof(&hdr->filetype_header), fd);
fwrite(&hdr->format_marker, sizeof(*hdr->format_marker), sizeof(&hdr->format_marker), fd);
fwrite(&hdr->data_header_length, sizeof(hdr->data_header_length), sizeof(&hdr->data_header_length), fd);
fwrite(&hdr->format_type, sizeof(hdr->format_type), sizeof(&hdr->format_type), fd);
fwrite(&hdr->number_of_channels, sizeof(hdr->number_of_channels), sizeof(&hdr->number_of_channels), fd);
fwrite(&hdr->sample_rate, sizeof(hdr->sample_rate), sizeof(&hdr->sample_rate), fd);
fwrite(&hdr->bytes_per_second, sizeof(hdr->bytes_per_second), sizeof(&hdr->bytes_per_second), fd);
fwrite(&hdr->bytes_per_frame, sizeof(hdr->bytes_per_frame), sizeof(&hdr->bytes_per_frame), fd);
fwrite(&hdr->bits_per_sample, sizeof(hdr->bits_per_sample), sizeof(&hdr->bits_per_sample), fd);
fwrite("data", 1, sizeof("data") - 1, fd);
uint32_t data_size = hdr->file_size - 36;
fwrite(&data_size, sizeof(data_size), sizeof(&data_size), fd);
return 0;
}
static int recordCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
PAData *data = (PAData*) userData;
const char *rptr = (const char*) inputBuffer;
char *wptr = &data->recordedSamples[data->frameIndex * 2 /*channels*/];
long framesToCalc;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if(framesLeft < framesPerBuffer)
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if(!inputBuffer)
{
for(long i = 0; i < framesToCalc; i++)
{
*wptr++ = 0; /* left */
*wptr++ = 0; /* right */
}
}
else
{
for(long i = 0; i < framesToCalc; i++)
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
}
data->frameIndex += framesToCalc;
return finished;
}
int recordWAV(const char *fileName, WaveHeader *hdr, uint32_t duration)
{
PaStreamParameters inputParameters;
PaStream* stream;
PaError err = paNoError;
PAData data;
int totalFrames;
int numSamples;
int numBytes;
char max, val;
double average;
printf("%d", hdr->bytes_per_second);
data.maxFrameIndex = totalFrames = duration * hdr->sample_rate; /* Record for a few seconds. */
data.frameIndex = 0;
numSamples = totalFrames * hdr->number_of_channels;
numBytes = numSamples;
data.recordedSamples = malloc(numBytes);
if(!data.recordedSamples)
{
printf("Could not allocate record array.\n");
goto done;
}
for(int i = 0; i < numSamples; i++) data.recordedSamples[i] = 0;
if((err = Pa_Initialize())) goto done;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = 2; /* stereo input */
inputParameters.sampleFormat = 1;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(&stream, &inputParameters, NULL, hdr->sample_rate, paFramesPerBufferUnspecified, paClipOff, recordCallback, &data);
if(err) goto done;
if((err = Pa_StartStream(stream))) goto done;
puts("Now recording!! Please speak into the microphone.");
while((err = Pa_IsStreamActive(stream)) == 1)
{
Pa_Sleep(1000);
printf("index = %d\n", data.frameIndex);
}
if( err < 0 ) goto done;
err = Pa_CloseStream(stream);
if(err) goto done;
/* Measure maximum peak amplitude. */
max = 0;
average = 0.0;
for(int i = 0; i < numSamples; i++)
{
val = data.recordedSamples[i];
val = abs(val);
if( val > max )
{
max = val;
}
average += val;
}
average /= (double)numSamples;
{
FILE* fid = fopen(fileName, "wb");
if(!fid) printf("Could not open file.");
else
{
writeWAVHeader(fid, hdr);
fwrite(data.recordedSamples, hdr->number_of_channels, totalFrames, fid);
fclose(fid);
}
}
done:
Pa_Terminate();
if(data.recordedSamples) /* Sure it is NULL or valid. */
free(data.recordedSamples);
if(err)
{
fprintf(stderr, "An error occured while using the portaudio stream\n");
fprintf(stderr, "Error number: %d\n", err);
fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
}
我在文件上运行的一些测试:
$ xxd -g1 test.wav | head
0000000: 52 49 46 46 00 00 00 30 00 00 00 30 57 41 56 45 RIFF...0...0WAVE
0000010: 66 6d 74 20 10 00 00 00 01 00 02 00 e0 ab 00 00 fmt ............
0000020: 80 af 02 00 04 00 10 00 57 41 56 45 66 6d 74 20 ........WAVEfmt
0000030: 66 6d 74 20 10 00 00 00 10 00 00 00 01 00 02 00 fmt ............
0000040: e0 ab 00 00 80 af 02 00 04 00 10 00 00 00 00 80 ................
0000050: 37 3d 04 10 00 00 03 00 01 00 02 00 e0 ab 00 00 7=..............
0000060: 80 af 02 00 04 00 10 00 02 00 e0 ab 00 00 80 af ................
0000070: 02 00 04 00 10 00 00 00 e0 ab 00 00 80 af 02 00 ................
0000080: 04 00 10 00 00 00 00 80 37 3d 04 10 00 00 03 00 ........7=......
0000090: 00 00 00 00 00 00 00 00 80 af 02 00 04 00 10 00 ................
$ file test.wav
test.wav: RIFF (little-endian) data
$ stat -f %s test.wav
stat: %s: bad format
我不太确定哪里出错了。我没有正确写出数据吗?
最佳答案
我不知道它的其余部分,但你的 fwrite
应该是这样的:
fwrite( hdr->RIFF_marker, sizeof(hdr->RIFF_marker), 1, fd);
fwrite(&hdr->file_size, sizeof(hdr->file_size), 1, fd);
fwrite( hdr->filetype_header, sizeof(hdr->filetype_header), 1, fd);
fwrite( hdr->format_marker, sizeof(hdr->format_marker), 1, fd);
fwrite(&hdr->data_header_length, sizeof(hdr->data_header_length), 1, fd);
fwrite(&hdr->format_type, sizeof(hdr->format_type), 1, fd);
fwrite(&hdr->number_of_channels, sizeof(hdr->number_of_channels), 1, fd);
fwrite(&hdr->sample_rate, sizeof(hdr->sample_rate), 1, fd);
fwrite(&hdr->bytes_per_second, sizeof(hdr->bytes_per_second), 1, fd);
fwrite(&hdr->bytes_per_frame, sizeof(hdr->bytes_per_frame), 1, fd);
fwrite(&hdr->bits_per_sample, sizeof(hdr->bits_per_sample), 1, fd);
fwrite("data", 4, 1, fd);
关于c - 生成错误的 WAV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23073389/
如果已知该确切样本存在于 wav 中的某处(但可能与其他声音混合),是否可以使用 FFT 找到较长 wav 中出现的小 wav 样本? 编辑 (收到两个回复后):如果我有一个包含所有已知声音的库,这些
我对 .NET 中的音频完全陌生,所以请多多包涵。 我的目标是创建一个具有两个 channel 的 wav 文件。左声道将包含语音消息(使用 SpeechSynthesizer 生成的流),右声道需要
我的大部分信息都来自其他stackoverflow帖子,但没有一个真正有用。 import UIKit import AVFoundation class FaceButtonSc
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 3 年前。
这可能是一个非常简单的问题;我将一个单声道 WAV 文件转换为一个 short[] 数组,并且我有一个将其写回 WAV 文件的函数。一切正常。 (writeBuffer 是 short[] 数组) b
我们的应用程序需要知道它加载的音频文件的样本数。我们使用的库可以可靠地确定采样率,但不能确定样本数。我们是否可以仅从文件大小和采样率来计算样本数? 最佳答案 马克说什么。不,通常您需要解释标题。但是,
我正在用java做一个项目,需要我加密wave文件。那么,是否有一个直接的过程可以将波形文件转换为二进制文件并返回?我将对二进制数据应用加密算法。 最佳答案 是的。 File file = new F
我想知道如何从 .wav 文件中获取样本以执行两个 .wav 文件的窗口连接。 谁能告诉我怎么做? 最佳答案 wave标准库的模块是关键:当然在代码顶部的 import wave 之后,wave.op
我有一个几分钟长的 .wav 文件,我想将其分成不同的 10 秒 .wav 文件。 到目前为止,这是我的 python 代码: import wave import math def main(fil
我在 ffmpeg 中使用以下命令合并多个 wav 文件: -f concat -safe 0 -i /storage/emulated/0/AudioClipsForSpeakerRecogniti
我正在尝试用python实现主动降噪。我的项目由两组代码组成: 录音代码 声音过滤代码 我的目标是当您运行该程序时,它将开始通过麦克风录音。录音完成后,会生成一个名为“file1.wav”的保存文件,
我正在尝试制作一个音乐识别系统。我担心我可能没有按照预期读取 wav 样本,而且我可能会应用错误的窗口大小来进行 FFT 和其他操作。 如果你能帮我的话,那就太好了。 首先,我有一些关于 Wavs 中
如何使用 java 合并两个 wav 文件? 我试过了 this但它没有正常工作,他们还有其他方法吗? 最佳答案 如果您直接处理 wav 文件的字节,您可以在任何编程语言中使用相同的策略。对于此示例,
尝试为我的 previous question 找到解决方法,我想将用 byte[](具有 wav header )编写的 16k 8 位单声道 wav 转换为 8k 8 位单声道流/字节 []。 是
目前我正在使用一个语音到文本的翻译模型,该模型采用 .wav 文件并将音频中的可听语音转换为文本转录本。该模型之前曾用于直接录制的 .wav 音频录音。但是现在我正在尝试对视频中最初出现的音频做同样的
试图在 python 中将 wav 文件转换为 wav uLaw。 使用 pydub 的 AudioSegment,我可以使用以下命令转换为 mp3: AudioSegment.from_wav(fr
我在 xcode 项目中添加了 LibFlac。然后我在我的项目中添加了来自 Libflac 的decode/main.c。我通过了 infile.flac 并运行了项目的可执行文件,但它给出了以下错
大家好,感谢您的阅读。 我想使用 Python 的 scipy.io.wavfile 对一首歌进行一些分析。由于我只有 .mp3 格式的歌曲,因此我使用 ffmpeg 将文件转换为 .wav,方法如下
我需要连接两个音频波,以便最终输出的音频波应该有一个更平滑的交汇点。我的意思是,在连接点,假设 10 秒钟,第一个音频应该开始淡出,而另一个音频开始拾取。 我已经能够连接两个音频文件并生成单个输出,但
我需要将一个 wav 文件转换为 8000Hz 16 位单声道 Wav。我已经有一个代码,它适用于 NAudio 库,但我想使用 MemoryStream 而不是临时文件。 using System.
我是一名优秀的程序员,十分优秀!