简体   繁体   English

如何降低Linux上WAV文件的质量和规格

[英]How to lower the quality and specs of a wav file on linux

So to preface my problem, I'll give some context. 因此,为了开始我的问题,我将提供一些背景信息。

In SDL2 you can load wav files such as from the 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);
}

The issue I'm getting from SDL_GetError is Complex WAVE files not supported 我从SDL_GetError得到的问题是Complex WAVE files not supported


Now the wav file I'm intending to open has the following properties: 现在,我打算打开的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

From the wiki.libsdl.org/SDL_OpenAudioDevice page and subsequent wiki.libsdl.org/SDL_AudioSpec#Remarks page I can at least surmise that a wav file of: 从wiki.libsdl.org/SDL_OpenAudioDevice页面和随后的wiki.libsdl.org/SDL_AudioSpec#Remarks页面,我至少可以推测出一个wav文件:

freq = 48000;
format = AUDIO_F32;
channels = 2;
samples = 4096;

quality should work. 质量应该起作用。

The main problem I can see is that my wav file has the s16le format whereas it's not listed on the SDL_AudioSpec page. 我可以看到的主要问题是我的wav文件具有s16le格式,而未在SDL_AudioSpec页面上列出。

This leads me to believe I need to reduce the quality of test.wav so it does not appear as "complex" in SDL. 这使我相信我需要降低test.wav的质量,因此它在SDL中不会显示为“复杂”。

When I search engine Complex WAVE files not supported nothing helpful comes up, except it appears in the SDL_Mixer library, which as far as I know I'm not using. 当我搜索Complex WAVE files not supported时,除了显示在SDL_Mixer库中(据我所知我没有使用)外,没有任何帮助。

Can the format be changed via ffmepg to work in SDL2? 可以通过ffmepg更改格式以在SDL2中工作吗?

Edit: This appears to be the actual code in SDL2 where it complains. 编辑:这似乎是SDL2中抱怨的实际代码。 I don't really know enough about C to dig all the way through the vast SDL2 library, but I thought it might help if someone notices something just from hinting variable names and such: 我对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;
}

After a couple hours of fun audio converting I got it working, will have to tweak it to try and get better sound quality. 经过几个小时的有趣的音频转换后,我开始使用它了,必须对其进行调整以尝试获得更好的音质。

To answer the question at hand, converting can be done by: 要回答眼前的问题,可以通过以下方式完成转换:

ffmpeg -i old.wav -acodec pcm_s16le -ac 1 -ar 16000 new.wav

To find codecs on your version of ffmpeg: 要在您的ffmpeg版本上找到编解码器,请执行以下操作:

ffmpeg -codecs

This format works with SDL. 此格式适用于SDL。

Next within SDL when setting the desired SDL_AudioSpec make sure to have the correct settings: 设置所需的SDL_AudioSpec时,SDL中的下一步要确保设置正确:

freq = 16000;
format = AUDIO_S16LSB;
channels = 2;
samples = 4096;

Finally the main issue was most likely using the legacy SDL_MixAudio instead of the newer SDL_MixAudioFormat 最后,主要问题很可能是使用旧版SDL_MixAudio而不是较新的SDL_MixAudioFormat

With the following settings: 使用以下设置:

SDL_MixAudioFormat(stream, mixData, AUDIO_S16LSB, len, SDL_MIX_MAXVOLUME / 2); as can be found on the wiki. 可以在Wiki上找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM