Added a basic Wav decoder. #984

Merged
merged 4 commits into from Aug 13, 2016

Projects

None yet

4 participants

@Rinnegatamante
Member

This fix the HUUUUGE loading time for WAV tracks on embedded systems
using libsndfile decoder. In the future when 3ds_decoder will be
removed, this should be used even on 3DS port probably.

@Ghabry Ghabry commented on an outdated diff Aug 10, 2016
src/decoder_wav.h
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EASYRPG_AUDIO_DECODER_WAV_H
+#define EASYRPG_AUDIO_DECODER_WAV_H
+
+// Headers
+#include "audio_decoder.h"
+#include <string>
+#include <memory>
+
+/**
+ * Audio decoder for WAV powered by libsndfile
@Ghabry
Ghabry Aug 10, 2016 Member

Update that comment

@Ghabry
Member
Ghabry commented Aug 10, 2016 edited

This is in general useful also for other systems.

To the other devs: Should this have some optional opt-in from configure.ac? Default on makes no sense to me on PC, because the IO is fast, but manual enabling could be useful for testing.
Also about the macro. Which one would you suggest? WANT_BUILTIN_WAV?

@Rinnegatamante
Please add these 2 new files to the "Makefile.am" in the root directory and to "builds/vs2015/PlayerLib.vcxproj" and "builds/vs2015/PlayerLib.vcxproj.filters"
In the filter file place them in the audio filter (<Filter>Source Files\Backend\Audio</Filter>)
The file formats should easy to understand.

Otherwise minor style issues:
Add spaces between "if" and "(", also between ")" and "{"
Add spaces between "=" and the variables: int decoded = fread
ifs followed by single statements: Move the statement on the next line

if (a > b)
    return 0;
@Ghabry Ghabry commented on an outdated diff Aug 10, 2016
src/decoder_wav.cpp
+ fseek(file_, 16, SEEK_SET);
+ fread(&jump, 4, 1, file_);
+
+ // Skipping to audiobuffer start
+ while (chunk != 0x61746164){
+ fseek(file_, jump, SEEK_CUR);
+ fread(&chunk, 4, 1, file_);
+ fread(&jump, 4, 1, file_);
+ }
+
+ audiobuf_offset = ftell(file_);
+ finished=false;
+ return file_!=NULL;
+}
+
+bool WavDecoder::Seek(size_t offset, Origin origin) {
@Ghabry
Ghabry Aug 10, 2016 Member

The Seek function completely ignores the "origin" argument (pass it through to fseek)

@Ghabry Ghabry commented on an outdated diff Aug 10, 2016
builds/psvita/Makefile
@@ -27,7 +27,7 @@ PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++
CFLAGS = -Wl,-q -O3 -DPSP2 -DHAVE_LIBSPEEXDSP \
- -DHAVE_SLOW_CPU -DSUPPORT_AUDIO -DHAVE_LIBSNDFILE \
+ -DWANT_FASTWAV=1 -DSUPPORT_AUDIO -DHAVE_LIBSNDFILE \
@Ghabry
Ghabry Aug 10, 2016 Member

That =1 thing was in FMMIDI because we offer 2 options (1 and 2). For your case this is not needed, you can remove the "=1"

@Ghabry Ghabry commented on an outdated diff Aug 10, 2016
src/audio_decoder.cpp
@@ -168,14 +168,14 @@ std::unique_ptr<AudioDecoder> AudioDecoder::Create(FILE* file, const std::string
#endif
}
-#ifdef HAVE_SLOW_CPU
+#if WANT_FASTWAV == 1
@Ghabry Ghabry commented on an outdated diff Aug 10, 2016
@@ -116,6 +116,12 @@
# endif
#endif
+#ifdef WANT_FASTWAV
+# if WANT_FASTWAV != 1
+# error "WANT_FASTWAV must be set to 1"
+# endif
+#endif
@Ghabry
Ghabry Aug 10, 2016 edited Member

also not needed g

@carstene1ns carstene1ns commented on an outdated diff Aug 10, 2016
src/decoder_wav.cpp
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EasyRPG Player is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "system.h"
+
+#ifdef HAVE_SLOW_CPU
@carstene1ns
carstene1ns Aug 10, 2016 Member

WANT_FASTWAV

@Ghabry
Member
Ghabry commented Aug 10, 2016 edited

I think we can squash the last 4 commits into one, because is just typo and style.
Next git lesson :P

git rebase -i HEAD~4

shows an editor of the last 4 commits (newest at the bottom)

Set the 3 last commits to "squash" (from pick) and keep the first line on "pick".

Squash merges the commit in the one above until it encounters a picked commit.

Save and quit, asks now for the commit message. Write a nice one (suggests all 4) and
git push -f origin as usual

@Ghabry
Member
Ghabry commented Aug 12, 2016

@fdelapena @carstene1ns
Do you think an entry to configure.ac /CMakeLists makes sense for this?

Probably not of much use on the desktop, has already libsndfile and SDL fallback and is fast enough.

@fdelapena
Member

IMHO it might be worth to fix libsndfile loading code to try preventing this behaviour, as several games use ADPCM and 24 bit PCM. Not sure how long will happen, but so far I don't know other ports with significant WAV slowdowns using autotools/cmake. Because 3DS is using its own Makefile, this could be deferred until at least confirming a possible libsndfile fix.

@Ghabry Ghabry self-assigned this Aug 12, 2016
@carstene1ns
Member

I think that libsndfile behaviour cannot be changed, as it will always try to fill in some information structure and therefore needs to know how much data the file has. Therefore this is a good addition. However, only for non-desktop systems, so not needed for autotools/cmake.

Btw. looking at the sdl/mixer/sound wave readers, there are some more formats that could be added to this, no idea if worth, as I do not know if used by a game.

@carstene1ns carstene1ns commented on the diff Aug 12, 2016
src/decoder_wav.cpp
+WavDecoder::~WavDecoder() {
+ if (file_ != NULL) {
+ fclose(file_);
+ }
+}
+
+bool WavDecoder::Open(FILE* file) {
+ file_=file;
+ uint32_t chunk = 0xDEADBEEF;
+ uint32_t jump;
+ fseek(file_, 22, SEEK_SET);
+ fread(&nchannels, 1, 2, file_);
+ fread(&samplerate, 1, 4, file_);
+ uint16_t bitspersample;
+ fread(&bitspersample, 1, 2, file_);
+ switch (bitspersample) {
@carstene1ns
carstene1ns Aug 12, 2016 Member

One thing to note here is that there are no error checks for invalid wave files (i.e. bad sample rate). But given the games have mostly been tested before, this problem should be minimal.

@Ghabry
Ghabry Aug 13, 2016 Member

Does this handle 24bit PCMs?

@carstene1ns
carstene1ns Aug 13, 2016 Member

No this will fail this switch and likely crash later, because output_format is not defined.
We could add a default: condition to this switch and return false; directly for 24 bit and broken files.

@Ghabry Ghabry commented on the diff Aug 13, 2016
src/audio_decoder.cpp
@@ -166,7 +167,25 @@ std::unique_ptr<AudioDecoder> AudioDecoder::Create(FILE* file, const std::string
# endif
#endif
}
+
+#ifdef WANT_FASTWAV
+ // Try to use a basic decoder for faster wav decoding if not ADPCM
+ if (!strncmp(magic, "RIFF", 4)) {
+ fseek(file, 20, SEEK_SET);
+ uint16_t raw_enc;
+ fread(&raw_enc, 2, 1, file);
+ fseek(file, 0, SEEK_SET);
+ if (raw_enc == 0x01) { // Codec is normal PCM
@Ghabry
Ghabry Aug 13, 2016 Member

Or does 24bit fail that check? (then is no problem)

@Rinnegatamante
Member

24 Bits are not supported since apparently there isn't a proper output format: https://github.com/Ghabry/easyrpg-player/blob/audio/src/audio_decoder.h#L38-L46

@carstene1ns
Member

Yes, but you should add it to the switch and return false then.

Rinnegatamante added some commits Aug 9, 2016
@Rinnegatamante Rinnegatamante Added a basic Wav decoder.
This fix the HUUUUGE loading time for WAV tracks on embedded systems
using libsndfile decoder. In the future when 3ds_decoder will be
removed, this should be used even on 3DS port probably.
26ede00
@Rinnegatamante Rinnegatamante Code restyle and some additions. 23cfe80
@Rinnegatamante Rinnegatamante Added WANT_FASTWAV to WII/3DS & 3DS Decoder cleanup
Added WANT_FASTWAV to WII/3DS & 3DS Decoder cleanup
babdb92
@Rinnegatamante Rinnegatamante Correctly handling uncommon formats.
Correctly handling uncommon formats.
a8469c5
@carstene1ns carstene1ns merged commit 9111417 into EasyRPG:master Aug 13, 2016

6 checks passed

Android (armeabi-v7a) Build finished.
Details
GNU/Linux Build finished.
Details
OSX Build finished.
Details
Windows (x64) Build finished.
Details
Windows (x86) Build finished.
Details
web Build finished.
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment