Skip to content

pleasemarkdarkly/adotcorporation

Repository files navigation

Interactive Objects / Fullplay Media Source Code

Ancient Code GitHub repo size GitHub language count GitHub top language GitHub pull requests

Development Board

The following codebase was developed at the aforementioned companies between 1998 and 2006. The code comprises of various configurations of an embedded media player or commonly known as mp3 players.

The software stack system supports a number of hardware architectures, specifically, Windows CE MIPS VR4111 (first generation PalmPC), Window CE Pocket PC Casseopia (VR4121), Microsoft's First Generation AutoPC (SH3), Cirrus Logic Maverick (7412) ARM7 @ 72 MHz. Additionally, the software sits on top of eCos.

The MIPSVR4111 powered PocketPC was the first embedded software mp3 (and Windows Media Audio) player ever, in 1998. So obviously it had to be super efficient.

The Dharma system (above) included all the peripherals and software needed to create any permutation of a digital media device you wanted. Centered around the (super low cost) Cirrus Logic Maverick 7212, an ARM7 with internal 32kb of SRAM and access to both 16bit or 32bit wide FLASH. As you can see from the picture above, the system supported ethernet, CD-ROM, HDD, Dataplay, SD, MMC, and Smart Media. Customers could configure arious sized LCD (2-bit, 4-bit) through the remaining GPIO pins. In the 1998 the feature set for differentiation was around storage - which also effected cost. Dharma also supported cutting edge formats such the supremely funded Dataplay.

Removed code

The Microsoft Windows Media Codec has been removed due to licensing restrictions.

FreeDB

The Repo has been updated with Git Large File Storage. Thus, the FreeDB (Open Source version of GraceNote) images were added.

MIT License

Developers listed in alphabetical order.

Copyright (c) 1998-2020 A DOT Corporation. Developers: Benjamin Eitzen, Dan Conti, Daniel Bolstad, Daniel Coughlin, Edward Miller, Ezra Dreisbach, James Zipperer, Teman Clark-Lindh, Kenneth Gordon, Matthew Tadd, Morgan Belford, Noah Maas, Phil Rutchman, and Todd Malsbury.

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

See License.MD file for complete License.

Background

Mp3 had just been approved for a streaming audio format, the RIO was released in Korea and the Sony mini-disc would not allow the writing of arbitrary data (the format capacity of 170MB was dedicated to the propritary ATRAC format). PC audio jukeboxes were not a thing, storage and RAM were prohibatively expensive. Palm Pilot was the dominate handheld. From the date of the idea to create an mp3 player for a pocket device, Ed Miller, Matt Tadd, and myself worked on a half dozen hardware platforms, none of which were powerful enough to decode faster than realtime, resulting in audio stuttering. First generation PocketPC, AutoPC, even the first generation mp3 player RIO (Micronas 3507D) were all unable work for various reasons. As stated earlier, Compact Flash storage was between 4 to 128 MBs, at about $1 per MB, and underwhelming to store 1 to 35 songs. Nonetheless, six months later, we recieved the Casio E-100 prototype, and our player worked, although the device plus storage was over $500._

Fixed point

The first Casio Palm PC, Casseopia running Microsoft Windows CE used the NEC VR4111 MIPS processor. I acquired the rights to a reference mp3 implementation, using this as a starting point, I analyzed the VR4111 processor specification and the output of C code from Microsft Visual Studio compiler for Windows CE. Inefficiencies in the compilation and unsupported assembly were significant issues to overcome. Below are the highlights. Developers Ezra Dreibach, Matt Tadd, and Edward Miller each contributed.

First moving floats to fixed point.

#ifdef REAL_IS_FIXED
#define WRITE_SAMPLE(samples, sum, clip)         \
    if (sum.i > (32767 << FRACBITS))             \
    {                                            \
        *(samples) = 0x7fff;                     \
    }                                            \
    else if (sum.i < (-32768 << FRACBITS))       \
    {                                            \
        *(samples) = -0x8000;                    \
    }                                            \
    else                                         \
    {                                            \
        *(samples) = (short)(sum.i >> FRACBITS); \
    }
#elif defined(REAL_IS_INT)

Create an abstraction for the fixed point mulitplication.

inline int mult_real(int a, int b)
{
    int result;

#if defined(UNDER_CE) && defined(OPT_MULTREAL) 
    #if defined(_MIPS_)     
#if 1
        __asm("mult %0,%1",a,b);
        __asm("mflo %t1");
        __asm("srl %t1,%t1,15");  //FRACBITS
        __asm("mfhi %t2");
        __asm("sll %t2,%t2,32-15"); //FRACBITS
        __asm("or %t2,%t2,%t1");
        __asm("sw %t2,0(%0)",&result); 
#else    
        __asm("mult %0,%1",a,b);
        __asm("mflo %t1");
        __asm("mfhi %t0");
        __asm("dsrl %t0,%t0,15");  //FRACBITS
        __asm("sw %t1,0(%0)",&result); 
#endif
    #elif defined(_SH3_)
        __asm("mov.l   @R4,R2",&b);
        __asm(
              "mov     #H'FFFFFFF1,R0\n"  //FFFFFFF1 = -15
              "mov.l   @R4,R3\n"
              "dmuls.l R3,R2\n"
              "sts     MACL,R3\n"
              "sts     MACH,R2\n"
              "shld    R0,R3\n"
              "mov     #D'17,R0\n"
              "shad    R0,R2\n"
              "or      R2,R3\n"
              "mov.l   R3,@R5\n",
              &a, &result);
    #elif defined(_SH4_)
        __asm("mov.l   @R4,R2\n"
              "mov.l   @R5,R3\n",&a,&b);
        __asm("dmuls.l R3,R2");
        __asm("sts     MACL,R3");
        __asm("sts     MACH,R0");
        __asm("mov     #-15,R1");  //FFFFFFF4 = -15              
        __asm("shld    R1,R3");
        __asm("mov     #17,R1");
        __asm("shld    R1,R0");
        __asm("or      R3,R0");
        __asm("mov.l   R0,@R4",&result);
    #endif
#else
     result = (int)((((LONGLONG)a)*((LONGLONG)b))>>FRACBITS);
#endif  //UNDER_CE
    return result;
}

And time the output. Basically, you need a second of audio to be decoded within a second.

Find processors which have special operations called multiply and accumilate. Using the MACC to speed up the decode process.

#elif defined(_MIPS_) && defined(MIPS_4111)
            LONGLONG _sum, tmp;
            _sum = 0;

            mips_macc(-*(--window), *b0++, &tmp);
            _sum += tmp;
            mips_macc(*(--window), *b0++, &tmp);
            _sum -= tmp;
            mips_macc(*(--window), *b0++, &tmp);
            _sum -= tmp;
      
            ...
      
            mips_macc_end(_sum, &sum);

NEC's VR4121 provided the madd16 operator which worked. And finally was able to ship with a digital media player, the first of its kind.

    __asm("lw %t3,0(%0);" //load pointer to first array in %t3
          "lw %t4,0(%1);" //load pointer to second array in %t4
          "mtlo zero;"      //clear accumulate register
          "mthi zero;",
          &window, &b0);

    __asm("lw %t5,0x0(%t3);" //load value from %t3 at offset 0 (index 0)
          "lw %t6,0x0(%t4);" //load value from %t4 at offset 0
          "madd16 %t5,%t6;"
          //".word 0x01AE0028;"    //macc %t5, %t6

          "lw %t5,0x4(%t3);"  //load value from %t3 at offset 4 (index 1)
          "sub %t5,zero,%t5;" //negate %t5
          "lw %t6,0x4(%t4);"  //load value from %t4 at offset 4
          "madd16 %t5,%t6;"
          //".word 0x01AE0028;"    //macc %t5, %t6

          "lw %t5,0x8(%t3);" //load value from %t3 at offset 8 (index 2)
          "lw %t6,0x8(%t4);" //load value from %t4 at offset 8
          "madd16 %t5,%t6;"
          //".word 0x01AE0028;" //macc %t5, %t6
    
           ...

Bonus

The above platform also encodes mp3 using the ARM7 inside 72MHz.

A DOT Corporation

ADOT

About

Source code for mp3 encoder, decoder and content management on ARM7 based devices.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published