如何在 linux 上降低 wav 文件的质量和规格
How to lower the quality and specs of a wav file on linux
因此,为了解决我的问题,我将提供一些背景信息。
在 SDL2 中,您可以加载来自 wiki 的 wav 文件:
SDL_AudioSpec wav_spec;
Uint32 wav_length;
Uint8 *wav_buffer;
/* Load the WAV */
if (SDL_LoadWAV("test.wav", &wav_spec, &wav_buffer, &wav_length) == NULL) {
fprintf(stderr, "Could not open test.wav: %s\n", SDL_GetError());
} else {
/* Do stuff with the WAV data, and then... */
SDL_FreeWAV(wav_buffer);
}
我从 SDL_GetError 得到的问题是 Complex WAVE files not supported
现在我要打开的 wav 文件具有以下属性:
Playing test.wav.
Detected file format: WAV / WAVE (Waveform Audio) (libavformat)
ID_AUDIO_ID=0
[lavf] stream 0: audio (pcm_s24le), -aid 0
Clip info:
encoded_by: Pro Tools
ID_CLIP_INFO_NAME0=encoded_by
ID_CLIP_INFO_VALUE0=Pro Tools
originator_reference:
ID_CLIP_INFO_NAME1=originator_reference
ID_CLIP_INFO_VALUE1=
date: 2016-05-1
ID_CLIP_INFO_NAME2=date
ID_CLIP_INFO_VALUE2=2016-05-1
creation_time: 20:13:34
ID_CLIP_INFO_NAME3=creation_time
ID_CLIP_INFO_VALUE3=20:13:34
time_reference:
ID_CLIP_INFO_NAME4=time_reference
ID_CLIP_INFO_VALUE4=
ID_CLIP_INFO_N=5
Load subtitles in dir/
ID_FILENAME=dir/test.wav
ID_DEMUXER=lavfpref
ID_AUDIO_FORMAT=1
ID_AUDIO_BITRATE=2304000
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
ID_START_TIME=0.00
ID_LENGTH=135.53
ID_SEEKABLE=1
ID_CHAPTERS=0
Selected audio codec: Uncompressed PCM [pcm]
AUDIO: 48000 Hz, 2 ch, s24le, 2304.0 kbit/100.00% (ratio: 288000->288000)
ID_AUDIO_BITRATE=2304000
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
AO: [pulse] 48000Hz 2ch s16le (2 bytes per sample)
ID_AUDIO_CODEC=pcm
从wiki.libsdl.org/SDL_OpenAudioDevice页面和随后的wiki.libsdl.org/SDL_AudioSpec#Remarks页面我至少可以推测出一个wav文件:
freq = 48000;
format = AUDIO_F32;
channels = 2;
samples = 4096;
质量应该有效。
我看到的主要问题是我的 wav 文件具有 s16le
格式,而 SDL_AudioSpec 页面上没有列出它。
这让我相信我需要降低 test.wav 的质量,这样它就不会在 SDL 中显示为 "complex"。
当我搜索引擎 Complex WAVE files not supported
时,除了它出现在 SDL_Mixer 库中之外,没有任何有用的结果,据我所知我没有使用它。
能否通过 ffmepg 更改格式以在 SDL2 中工作?
编辑: 这似乎是它抱怨的 SDL2 中的实际代码。我对 C 的了解还不够,无法深入挖掘庞大的 SDL2 库,但我认为,如果有人仅通过提示变量名等注意到某些内容,这可能会有所帮助:
/* Read the audio data format chunk */
chunk.data = NULL;
do {
if ( chunk.data != NULL ) {
SDL_free(chunk.data);
chunk.data = NULL;
}
lenread = ReadChunk(src, &chunk);
if ( lenread < 0 ) {
was_error = 1;
goto done;
}
/* 2 Uint32's for chunk header+len, plus the lenread */
headerDiff += lenread + 2 * sizeof(Uint32);
} while ( (chunk.magic == FACT) || (chunk.magic == LIST) );
/* Decode the audio data format */
format = (WaveFMT *)chunk.data;
if ( chunk.magic != FMT ) {
SDL_SetError("Complex WAVE files not supported");
was_error = 1;
goto done;
}
经过几个小时有趣的音频转换后,我开始工作了,将不得不对其进行调整以尝试获得更好的音质。
要回答手头的问题,可以通过以下方式进行转换:
ffmpeg -i old.wav -acodec pcm_s16le -ac 1 -ar 16000 new.wav
要在您的 ffmpeg 版本上查找编解码器:
ffmpeg -codecs
此格式适用于 SDL。
接下来在 SDL 中设置 所需 SDL_AudioSpec 确保设置正确:
freq = 16000;
format = AUDIO_S16LSB;
channels = 2;
samples = 4096;
最后,主要问题很可能是使用旧版 SDL_MixAudio
而不是较新的 SDL_MixAudioFormat
具有以下设置:
SDL_MixAudioFormat(stream, mixData, AUDIO_S16LSB, len, SDL_MIX_MAXVOLUME / 2);
可以在 wiki 上找到。
因此,为了解决我的问题,我将提供一些背景信息。
在 SDL2 中,您可以加载来自 wiki 的 wav 文件:
SDL_AudioSpec wav_spec;
Uint32 wav_length;
Uint8 *wav_buffer;
/* Load the WAV */
if (SDL_LoadWAV("test.wav", &wav_spec, &wav_buffer, &wav_length) == NULL) {
fprintf(stderr, "Could not open test.wav: %s\n", SDL_GetError());
} else {
/* Do stuff with the WAV data, and then... */
SDL_FreeWAV(wav_buffer);
}
我从 SDL_GetError 得到的问题是 Complex WAVE files not supported
现在我要打开的 wav 文件具有以下属性:
Playing test.wav.
Detected file format: WAV / WAVE (Waveform Audio) (libavformat)
ID_AUDIO_ID=0
[lavf] stream 0: audio (pcm_s24le), -aid 0
Clip info:
encoded_by: Pro Tools
ID_CLIP_INFO_NAME0=encoded_by
ID_CLIP_INFO_VALUE0=Pro Tools
originator_reference:
ID_CLIP_INFO_NAME1=originator_reference
ID_CLIP_INFO_VALUE1=
date: 2016-05-1
ID_CLIP_INFO_NAME2=date
ID_CLIP_INFO_VALUE2=2016-05-1
creation_time: 20:13:34
ID_CLIP_INFO_NAME3=creation_time
ID_CLIP_INFO_VALUE3=20:13:34
time_reference:
ID_CLIP_INFO_NAME4=time_reference
ID_CLIP_INFO_VALUE4=
ID_CLIP_INFO_N=5
Load subtitles in dir/
ID_FILENAME=dir/test.wav
ID_DEMUXER=lavfpref
ID_AUDIO_FORMAT=1
ID_AUDIO_BITRATE=2304000
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
ID_START_TIME=0.00
ID_LENGTH=135.53
ID_SEEKABLE=1
ID_CHAPTERS=0
Selected audio codec: Uncompressed PCM [pcm]
AUDIO: 48000 Hz, 2 ch, s24le, 2304.0 kbit/100.00% (ratio: 288000->288000)
ID_AUDIO_BITRATE=2304000
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
AO: [pulse] 48000Hz 2ch s16le (2 bytes per sample)
ID_AUDIO_CODEC=pcm
从wiki.libsdl.org/SDL_OpenAudioDevice页面和随后的wiki.libsdl.org/SDL_AudioSpec#Remarks页面我至少可以推测出一个wav文件:
freq = 48000;
format = AUDIO_F32;
channels = 2;
samples = 4096;
质量应该有效。
我看到的主要问题是我的 wav 文件具有 s16le
格式,而 SDL_AudioSpec 页面上没有列出它。
这让我相信我需要降低 test.wav 的质量,这样它就不会在 SDL 中显示为 "complex"。
当我搜索引擎 Complex WAVE files not supported
时,除了它出现在 SDL_Mixer 库中之外,没有任何有用的结果,据我所知我没有使用它。
能否通过 ffmepg 更改格式以在 SDL2 中工作?
编辑: 这似乎是它抱怨的 SDL2 中的实际代码。我对 C 的了解还不够,无法深入挖掘庞大的 SDL2 库,但我认为,如果有人仅通过提示变量名等注意到某些内容,这可能会有所帮助:
/* Read the audio data format chunk */
chunk.data = NULL;
do {
if ( chunk.data != NULL ) {
SDL_free(chunk.data);
chunk.data = NULL;
}
lenread = ReadChunk(src, &chunk);
if ( lenread < 0 ) {
was_error = 1;
goto done;
}
/* 2 Uint32's for chunk header+len, plus the lenread */
headerDiff += lenread + 2 * sizeof(Uint32);
} while ( (chunk.magic == FACT) || (chunk.magic == LIST) );
/* Decode the audio data format */
format = (WaveFMT *)chunk.data;
if ( chunk.magic != FMT ) {
SDL_SetError("Complex WAVE files not supported");
was_error = 1;
goto done;
}
经过几个小时有趣的音频转换后,我开始工作了,将不得不对其进行调整以尝试获得更好的音质。
要回答手头的问题,可以通过以下方式进行转换:
ffmpeg -i old.wav -acodec pcm_s16le -ac 1 -ar 16000 new.wav
要在您的 ffmpeg 版本上查找编解码器:
ffmpeg -codecs
此格式适用于 SDL。
接下来在 SDL 中设置 所需 SDL_AudioSpec 确保设置正确:
freq = 16000;
format = AUDIO_S16LSB;
channels = 2;
samples = 4096;
最后,主要问题很可能是使用旧版 SDL_MixAudio
而不是较新的 SDL_MixAudioFormat
具有以下设置:
SDL_MixAudioFormat(stream, mixData, AUDIO_S16LSB, len, SDL_MIX_MAXVOLUME / 2);
可以在 wiki 上找到。