

                    AudioMPEG V0.33, an audio MPEG decoder


Introduction


This module is supplied for free and without any warranty. No responsibility
will be taken for damages caused by it. You have been warned, if it scrambles
your harddisk or lets your monitor implode - it is all your own fault.

Big thanks go to Robin Watts from Warm Silence Software for helping with
his Callback support code for calling C functions back.

If you want to use this module in your own programs, you should ensure the
following:

1. You should install the module to System:Modules as your program will
   not be the only one to use this module
2. You should credit Peter in the info window of your program or in another
   way if it has nothing like that

Also supplied is MP3Abs, an MP3 to WAV converter, and examples of how to use
the module.

Warning: all the supplied code requires a StrongARM processor.


Contacts


If you want to contact me:

email: fa044826@skynet.be


Hardware requirements


The module is only suitable for Strongarm RiscPCs, not only because of the
speed but also because it uses long multiply instructions.


Interface


The module is used in the following way:

1. Call SWI AudioMPEG_Init. The module will allocate 2 dynamic areas for 2
   circular buffers (input and output) and return the pointers to the
   buffers.

2. Start feeding the data of your stream into the input buffer, until
   a call to SWI AudioMPEG_Info does not return 0 anymore. Read the info
   about the stream returned by the AudioMPEG_Info call.
   
3. Continue feeding stream data into the input buffer and start reading the
   decoded sample data (signed 16bit) from the output buffer.

4. If the stream is finished, empty the output buffer before calling
   SWI AudioMPEG_Quit


Troubleshooting


AudioMPEG cannot be RMKilled when streams are still active. If an application
using AudioMPEG crashes and you whishes to get rid of the module, from BASIC
type SYS "AudioMPEG_Configure",-1 to force it to close all the streams.

   
Decoding Speed


The module decodes as fast as it can provided there is enough space in the
output buffer, and input data is fed fast enough into the input buffer. On
200 MHz Strongarm systems it reaches 3x realtime speed for a 128kbits/s
frame rate. If you want to use it for realtime playback and do not want it to
use all your CPU time, simply only read in playback speed from the output
buffer, and read only small amounts at once. The way you read from the output
buffer has a direct influence at the usability of the computer.                



                                 SWI Interface

   
Warning: on SWI exit flags are corrupted.


AudioMPEG_Init (0x52180)


  On entry

    R0 = code number which is needed to be allowed to call all other SWIs
         and which identifies your stream. Ensure it is unlikely for other
         tasks to use the same code, for example by using as code a pointer
         to one of your data structures.

  On exit

    If the module is already in use (no free buffers):
      R0 = -1
    Otherwise:
      R0 = pointer to input buffer (dynamic area)
      R1 = pointer to sound output buffer (dynamic area)

This SWI needs to be called to initialize the decoding procedure, it
allocates input and output buffer and returns their addresses.

The input buffer looks like this (C syntax):

typedef struct {
  int size;         //size of data in bytes
  int start;        //start position of data in the buffer
  int free;         //start position of free space in the buffer
  int finished;     //needs to be set to 1 if the input is finished
  int dummy[12];
  char data[];      //array of <size> bytes
} mp3buf;

and the output buffer like that:

typedef struct {
  int size;         //size of data in 16 bit words (512*1024)
  int start;        //start position of data in the buffer
  int free;         //start position of free space in the buffer
  int finished;     //will be set to 1 if the output is finished
  int dummy[12];
  short data[];     //array of <size> 16 bit words
} sndbuf;

Both buffers are circular buffers, and they are not allowed to be completely
filled. That means if start is equal to free, the buffer is empty.
As you see they are nearly identical, the only difference is that the input
buffer counts bytes (8bit), and the output buffer counts shorts (16bit).

The program using the AudioMPEG decoder module is only allowed to change
<free> in the input buffer if it puts new data into the input buffer. It must
ensure that the input buffer never is completely filled. If the input
stream is finished it should set <finished> in the input buffer to 1.
It is also allowed to change <start> in the output buffer if it reads audio
data from the output buffer. Under nocircumstances it should change <start>
in the input buffer or <free> in the output buffer.


AudioMPEG_Quit (0x52181)


  On entry

    R0 = the code number, this is to provide a bit safety

  On exit

    If all went ok:
      R0 = 0
    If the code was wrong or there is no stream to quit:
      R0 = -1

This SWI will remove input and output buffer and finish decoding.


AudioMPEG_Info (0x52182)


  On entry

    R0 = the code number

  On exit

    If all went ok:
      R0 = pointer to an info-structure about the stream
    If the module still does not know the information required, if that
    happens you should wait a bit or start feeding data into the module
    If you not already did it:
      R0 = 0
    If an error occured:
      R0 = 1
    If the code was wrong or there is no stream that gets decoded:
      R0 = -1

This SWI will return some information.

info-structure:

typedef struct {
  int version;      // 0 for MPEG-2 LSF, 1 for MPEG-1, 2 for MPEG-2.5 LSF
  int layer;        // Layer number
  int bitrate;      // kbits/sec
  int samplerate;   // samples/sec 
  int channels;     // 1=mono, 2=stereo
} mp3info;


AudioMPEG_Clear (0x52183)


  On entry

    R0 = the code number
    R1 = Bit 0 set -> input buffer cleared
         Bit 1 set -> output buffer cleared
         Bit 2 set -> mp3info is reset (otherwise the frame header seeking
                      routines continue to check that version, layer, sample
                      rate and channels remain identical while validating
                      the new headers).

  On exit

    -


AudioMPEG_Attach (0x52184)


  On entry

    R0 = the code number
    R1 = pointer to input buffer (dynamic area)

  On exit

    If the module is already in use (no free buffers):
      R0 = -1
    Otherwise:
      R0 = pointer to input buffer (dynamic area)
      R1 = pointer to sound output buffer (dynamic area)

Same as AudioMPEG_Init but will caller providing input buffer.


AudioMPEG_Configure (0x52185)


  On entry

    R0 = the code number
    R1... = values

  On exit

    R1... = values

  Codes

    0, R1 = input buffer size in KBs, 0 to read
    1, R1 = output buffer size in KBs, 0 to read 

    In v0.17
    -1, close all streams (use it only in case of trouble)


AudioMPEG_Process (0x52186)


  On entry

    R0 = the code number

  On exit

    -

Calls the decoding process in foreground instead all waiting for calbacks
to perform the job. Once this call is used for a stream the callbacks are
disabled for that stream.


                                    History

Peter Teichmann
0.01    17-03.1999  first released version
0.02    18-03.1999  improved handling of errors in streams
0.03    22-03.1999  fixed "bug" with input buffer handling
0.04                reorganized memory handling
0.05    01-04.1999  fixed bug with layer 2 introduced in 0.04
0.06    08-04.1999  better balanced cpu usage
0.07    08-04.1999  fixed bug that could cause an output buffer overflow
                    under some circumstances
0.08    12-04.1999  fixed bug with error handling if sync can not be found
0.09    04-05.1999  uses about 5% less CPU time, dct36 coded in assembler
0.10    05-05.1999  improvements in hufman_decode save another 3% of CPU time
0.11    22-07.1999  added SWI for clearing buffers

Andr Timmermans
0.12    01-05-2000  Made some routines faster:
                    - III_hufman_decode
                    - III_dequantize_sample
                    - III_reorder
                    - III_stereo
                    Rewrote header seeking and some related routines, which
                    makes the player more reliable.
                    Fixed bug in bytes keeping from previous frame (layer3).
                    Added some support for MPEG 2.5.
0.13    05-05-2000  Fixed overflow in dct64 part of subbandsynthesis.
                    Reorganised the file structure.
                    Modified bs_keepBytes to insert null bytes in main data
                    buffer when number of bytes to keep from previous
                    frame is negative (much better for file positionning).
        07-07-2000  Made out_fifo and III_huffman_decode faster.
                    Modified III_hybrid for MPEG 2.5.
                    Modified bg_task so that callbacks are still generated
                    when output is finished (so that calling clearing SWI
                    allows new input will be decode at the end of the old
                    input).
0.14    09-09-2000  Error in original DCT64, there should be no >> 1
                    in the final stage.
        11-05-2000  Forgot to read CRC in case of layer 3, implemented
                    the check for layer 3.
0.15    22-05-2000  The tests files for layer 2 work without clipping
                    if I add 1 to the scalefactor indexes (this scales
                    the output by 2*exp(-1/3)). Having checked several
                    sources I think it must be a bug in the encoder used
                    for these files, anyway this allows me to remove the
                    division by 2 present to avoid clipping.
        23-05-2000  I have disabled CRC check because of a stupid MP3
                    encoder which leaves the CRC field to 0!!!!
0.16    29-09-2000  Skip RIFF-Wave and ID3v2 headers in first buffer.
                    Return bitrate as the mean bitrate of 2 frames
                    as some encoders alternate 2 bitrates (the bitrate
                    is still incorrect for VBR files).
        30-09-2000  The module can decode several streams at once:
                    two actually, because for more even the SA remains
                    processing callbacks and never return in user mode.
        27-10-2000  Added configuration of buffer sizes.
        31-10-2000  dct12 routine could give different results for the same
                    input, seems a bug in the Acorn C compiler. Moving the
                    declaration of every variable to the beginning of the
                    procedure solved the problem.
0.17    04-01-2001  Another speed optimisation.
        20-01-2001  Made the necessary changes to be 32-bit ready.
        24-02-2001  Used properties of Han window and dct64 to reduce
                    memory usage and increase speed.
        17-04-2001  part of III_dequantise_sample moved to assembler.
        18-04-2001  Recompiled in 26-bit due to lack of official 32-bit support.
0.18    28-05-2001  Optimisation in hufmann decoding.
0.19    19-07-2001  Hufmann decoding which could crash on bad streams.
        20-10-2001  New optimisation of Hufmann decoding (bitmasking).
        24-11-2001  Fix for MPEG layer 1.
0.20    30-03-2002  Some optimisations for layer 2.
0.21    02-08-2002  Fix for MPEG 2 layer3: bad region1 for window_switching.
        10-11-2002  Could lock the machine when attempting to play non-MP3.
0.22    09-02-2003  Silencing of corrupted frames.
0.23    24-05-2003  Rewrote delimitation of the amount of work performed
                    in one callback.
0.24    24-09-2003  Fixed bug introduced in 0.23.
0.25    21-02-2004  Fixed a bug in subband synthesis which could slightly
                    corrupt one sample out of 32.
                    Fixed layer I and II unquantization multipliers and
                    improved accuracy of layer III so that all the reference
                    streams are now decoded perfectly (for 16-bit accuracy).
0.26    15-05-2004  Fix for inverted table usage for MPEG2 Intensity Stereo.
0.27    06-12-2004  Added check for support of 64-bit multiplications
                    in module initialisation.
0.28    05-04-2006  SharedCLibrary neutral version.
0.29    27-08-2006  More detection and silencing of corrupted frames.
0.30    20-11-2007  Support for VBRI headers.
0.31    03-12-2009  ARMv7 compatibility.
0.32    25-01-2010  Fix AudioMPEG_Info to report 1, when end of stream
                    reached without being able to get the MPEG info.
0.33    05-06-2017  New SWI_Process to work without waiting callbacks.