Page 1 of 1

Fixed point math MP3 encoder

PostPosted: Sat Jun 16, 2012 10:26 pm
by patters
This seems to be pretty much forgotten:
http://sourceforge.net/projects/libshine-fxp/

The Shine encoder was originally written by one of the LAME devs as a lean and simple MP3 encoder, then someone else fixed it to remove all FPU math and adapted it for RiscOS. Then later someone cleaned it up for regular Linux use.
I downloaded it, renamed Makefile-generic to Makefile, edited the gcc line in that file to remove the "-m32" option and it compiles ok (just run make in that folder). I just tested ./shineenc-gen on my ARM NAS:

3m48 WAV file ripped from CD (Aphex Twin - Pulsewidth.wav):
lame 3.99-5 (from ipkg) @128Kbps - encoded in 6min09secs
shineenc v1.01 @128Kbps - encoded in 42secs
shineenc v1.01 @320Kbps - encoded in 46secs (Sounds perfectly fine on headphones to me, though my test track isn't ideal for assessing quality. Guitar music might be better to show up any problems).

This is a huge speed improvement over LAME on ARM CPU - 13x faster! Apparently the audio quality isn't quite as good as LAME because the encoder is not as complex, but since it's only an additional 10% time penalty to encode at 320Kbps then it might as well be used at that bitrate. The goal is only to transcode audio when devices won't play mp4, wma or flac or whatever.

So I wonder if this might be usable via a wrapper script to replace FFmpeg's libmp3lame encoder. I guess the main problem is that it's expecting a wav file input. Using a wrapper I guess you'd need to wait for the entire source file decode to happen first, then feed that wav into shineenc before you could start playing the transcoded file. I checked to see if FFmpeg supports using this lib (libshine-fxp) but no sign of that unfortunately. I guess it could be hacked in, but you'd need to know your way around the FFmpeg sources (or perhaps it's not that hard - here is an example of changes to graft in support for another lib: https://lists.ffmpeg.org/pipermail/ffmp ... 43788.html).

Anyway, it's something to think about and maybe experiment with, since it brings realtime audio transcoding to low power systems. Currently FFmpeg's ac3 encoder is the only one that is efficient enough for ARM CPUs to transcode in realtime.

My compiled binary (with source) for ARM Synology NAS (Marvell 628x):
http://dl.dropbox.com/u/1188556/libshine-fxp.tgz

Re: Fixed point math MP3 encoder

PostPosted: Sun Jun 17, 2012 1:18 am
by patters
I have suggested it as a possible enhancement to FFmpeg, since it would be very useful for transcoding for playback on FlowPlayer (mp3 or aac only).
https://ffmpeg.org/trac/ffmpeg/ticket/1457

Re: Fixed point math MP3 encoder

PostPosted: Wed Jan 02, 2013 1:48 am
by patters
richardpl who has replied to that ticket has developed a wrapper for a cleaned up version of the libtool-ized version of the shine encoder (savonet-shine), but it hasn't been merged into FFmpeg yet (it doesn't seem to interest many people for some reason). I have been able to build working compile for ARM Synology NAS and I can confirm that it's now perfectly possible to realtime transcode audio to MP3 on ARM. I also made a wrapper script to make the command line susbstitution for Serviio. FFmpeg with libshine was very tricky to build on ARM, but I have documented the process here:
http://pcloadletter.co.uk/2012/10/12/ff ... -synology/

Here's my wrapper script for reference:
  Code:
#!/bin/sh

#FFmpeg wrapper script to use libshine fixed point maths MP3 encoder on ARM CPUs
#as originally posted here: http://forum.serviio.org/viewtopic.php?f=7&t=6458
#patched build of FFmpeg req'd: http://pcloadletter.co.uk/2012/10/12/ffmpeg-shared-libs-for-synology/

PARAMS=""
FFMPEG_BIN="ffmpeg"
INPUT=0
for PARAM in "$@"; do
  if [ ${INPUT} = 1 ]; then
    #the FFmpeg input filename/URL needs quotes adding back on
    #because it may contain spaces, and the shell has removed them
    PARAMS="${PARAMS} \"${PARAM}\""
    INPUT=0
  else
    PARAMS="${PARAMS} ${PARAM}"
  fi
  if [ "${PARAM}" == "-i" ]; then
    #this loop is the -i parameter, the next loop will be the input filename/URL
    INPUT=1
  fi
done

#make libshine encoder substitution, 320kbps since it's no more expensive
if [ "${PARAMS}" != "${PARAMS/libmp3lame/}" ] || [ "${PARAMS}" != "${PARAMS/-f mp3/}" ]; then
  PARAMS="`echo ${PARAMS} | sed -r "s|libmp3lame|libshine|;s|-b:a [0-9]+k|-b:a 320k|"`"
fi

#invoke FFmpeg
FOLDER="`dirname $0`"
echo "${FOLDER}/${FFMPEG_BIN} ${PARAMS}" > ${FOLDER}/../log/ffmpeg-wrapper.log
#need to use eval here otherwise the quotes aren't handled properly
#http://fvue.nl/wiki/Bash:_Why_use_eval_with_variable_expansion%3F
eval ${FOLDER}/${FFMPEG_BIN} ${PARAMS}

#return FFmpeg status
exit $?

Re: Fixed point math MP3 encoder

PostPosted: Thu Jan 03, 2013 3:25 am
by slyguy42o
very cool, nice work.

Re: Fixed point math MP3 encoder

PostPosted: Wed Mar 06, 2013 1:38 pm
by fremske
Hi Patters,

Would it be possible to also use your wrapper and shin coding in the following setup?

*I have a Zyxel NSA310 (1.2 ghz mv6282 SoC), with 256DDR.
*I have FFP (fonz fun_plug) 7.0 installed, with Java 7, LAME 3.99.5 and FFmpeg 0.11.1.
*On top I am running Serviio 1.1 (see link: viewtopic.php?f=14&t=8933)

Can you tell me which steps I need to perform to enable shin coding with your wrapper?

Thank you very much!

Greetz,
Fremko

Re: Fixed point math MP3 encoder

PostPosted: Wed Mar 26, 2014 8:22 pm
by Xmantium
There has been someone who revived the shine mp3 encoder here - https://github.com/savonet/shine

Been using this on my QNAP ARM model and works very well.

Download section here - https://github.com/savonet/shine/releases

Re: Fixed point math MP3 encoder

PostPosted: Wed Mar 26, 2014 8:44 pm
by grolschie
I'm interested in faster MP3 transcoding with Serviio. Will building ffmpeg with libshine make MP3 encoding significantly faster on older x86 machines? And if so, any changes necessary for it to work with Serviio (e.g. FFmpeg wrapper)? Thanks.

Re: Fixed point math MP3 encoder

PostPosted: Thu Mar 27, 2014 6:30 am
by Xmantium
On ARM chips is a massive improvement! Not much on x86 chips. Serviio support Lame currently but you can to use a script to force FFmpeg to encode with Shine instead.
How fast is it? Tests from the gibhub show:

On a Raspberry Pi (ARM, no FPU):
Lame, 8minutes 53seconds:

pi@raspbmc:/tmp$ lame /tmp/bla.wav /tmp/bla.mp3
LAME 3.98.4 32bits (http://www.mp3dev.org/)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding /tmp/bla.wav to /tmp/bla.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3
Frame | CPU time/estim | REAL time/estim | play/CPU | ETA
5763/5764 (100%)| 8:44/ 8:44| 8:53/ 8:53| 0.2871x| 0:00
kbps LR MS % long switch short %
128.0 47.8 52.2 98.1 1.2 0.7
Writing LAME Tag...done
ReplayGain: -4.9d

Shine, 47seconds:

pi@raspbmc:/tmp$ shineenc /tmp/bla.wav /tmp/bla.mp3
shineenc (Liquidsoap version)
WAV PCM DATA, stereo 44100Hz 16bit, Length: 0: 2:30
MPEG-I layer III, stereo Psychoacoustic Model: Shine
Bitrate=128 kbps De-emphasis: none Original
Encoding "/tmp/bla.wav" to "/tmp/bla.mp3"
Finished in 0: 0:47
The difference is quite remarkable...!

Now, on a mac airbook (x86_64, FPU):
Lame, 9seconds:

toots@zulu /tmp % lame /tmp/bla.wav /tmp/bla.mp3
LAME 3.99.5 64bits (http://lame.sf.net)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding /tmp/bla.wav to /tmp/bla.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3
Frame | CPU time/estim | REAL time/estim | play/CPU | ETA
5763/5763 (100%)| 0:07/ 0:07| 0:09/ 0:09| 18.924x| 0:00
kbps LR MS % long switch short %
128.0 55.5 44.5 97.6 1.4 1.0
Writing LAME Tag...done
ReplayGain: -4.9dB

Shine, 5seconds:

toots@zulu /tmp % shineenc /tmp/bla.wav /tmp/bla.mp3
shineenc (Liquidsoap version)
WAV PCM DATA, stereo 44100Hz 16bit, Length: 0: 2:30
MPEG-I layer III, stereo Psychoacoustic Model: Shine
Bitrate=128 kbps De-emphasis: none Original
Encoding "/tmp/bla.wav" to "/tmp/bla.mp3"
Finished in 0: 0: 5

Re: Fixed point math MP3 encoder

PostPosted: Thu Mar 27, 2014 7:57 pm
by grolschie
Thanks for that.

Re: Fixed point math MP3 encoder

PostPosted: Thu Mar 31, 2016 5:52 pm
by norm
Unfortunately this doesn't seem to have been included in 1.6.1 even though it is mentioned in the release notes.
http://www.serviio.org/download/9-release-notes/92-release-notes-1-6-1

Serviio is reporting this
  Code:
2016-03-31 17:37:18,881 INFO  [FFMPEG] FFmpeg details: [version=2.1.8-compiled_by_barmalej2_for_ffp0.7arm, libRtpmPresent=true, libAssPresent=true, libShinePresent=true]

in the log. Although it does not seem to use the -codec:a libshine ffmpeg switch. Eg
  Code:
root     29526 63.6  1.9  26008  9788 ?        R    18:34   0:13 /ffp/opt/serviio/bin/ffmpeg -threads 1 -i /i-data/md0/music/Adele/21/01-adele-rolling_in_the_deep.flac -y -threads 1 -b:a 192k -id3v2_version 3 -ac 2 -c:v copy -f mp3 /i-data/md0/wip/serviio/tmp/Serviio/transcoding-temp-235-flv_player-ORIGINAL.stf