_source/MungeBuffer.c

/*
    File:       MungeBuffer.c
 
    Contains:   Routines demonstrating how to manipulate buffers of WAVE data to get them to play correctly.
 
    Written by: Mark Cookson    
 
    Copyright:  Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                8/31/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
#include "MungeBuffer.h"
 
/* This PowerPC assembly routine is used to make a buffer of WAVE sound
   data play as if it was a buffer of a AIFF sound data.
 
   All this really means is that you have to do the endian conversion without
   rearanging the channels if the sound is stereo.
 
   The buffer addressed is passed in register r3 and the count is passed in r4.
*/
#ifdef ASM  // Should we use the assembly versions or the C versions of the buffer munging routines?
 
#ifdef powerc
 
asm void Endian16BitBuffer (Ptr buf, unsigned long count)
{
#pragma unused (buf, count)
        b       test                        // Make sure count is good
more:   subi    r4, r4, 0x04                // Move pointer back 4 bytes to next long
        lwzx    r5, r3, r4                  // Load the long
        rlwinm  r5, r5, 0x10, 0x00, 0x1F    // Rotate long left 16 bits
        stwbrx  r5, r3, r4                  // Write it back out byte reversed
test:   cmpwi   r4, 0x03                    // Are we done yet?
        bgt     more                        // Go back to process more longs
        blr                                 // We're outta here
}
 
/* These are the coresponding 68K versions of the above PowerPC assembly buffer munging routines.
 
   These calls will be called if the target is a 68K based Mac.
 
   The buffer address is passed as the second value (from the top) of the stack, and the count
   is the third value (from the top) of the stack.
*/
 
#else //generating 68K
 
asm void Endian16BitBuffer (Ptr buf, unsigned long count)
{
        movea.l 0x04(sp), a0                // Put address of buffer in a0
        move.l  0x08(sp), d0                // Put count in d0
        lsr.l   #0x02, d0                   // Divide count by 4
        bra     test                        // Make sure count is good
more:   move.l  (a0), d1                    // Load the long
        ror.w   #0x08, d1                   // Rotate bottom 16 bits
        swap    d1                          // Swap upper and lower words of d1
        ror.w   #0x08, d1                   // Rotate bottom 16 bits (used to be top bits)
        swap    d1                          // Swap upper and lower words of d1
        move.l  d1, (a0)+                   // Store the result
test:   dbra    d0, more                    // Go back and process more longs
        rts                                 // We're outta here
}
 
#endif
 
#else
 
/* Use C functions instead of assembly functions.
   To use these functions, undefine ASM in MungeBuffer.h.
*/
 
void Endian16BitBuffer (Ptr buf, unsigned long count)
{
    unsigned long   i;
    unsigned char   tempChar;
 
    for (i = kStartOfBuffer; i < count; i += sizeof (short)) {
        tempChar = (buf)[i];
        (buf)[i] = (buf)[i+1];
        (buf)[i+1] = tempChar;
    }
}
 
#endif
 
void ReverseMono8BitBuffer (const Ptr buf, unsigned long count)
{
    unsigned char   *endBuffer;
    unsigned char   *startBuffer = (unsigned char *)buf;
    unsigned char   saveByte;
    long            i;
 
    endBuffer = ((unsigned char *)buf + count) - 1;
    for (i = (count / (sizeof (char) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
        saveByte = *endBuffer;
        *endBuffer-- = *startBuffer;
        *startBuffer++ = saveByte;
    }
}
 
void ReverseStereo8BitBuffer (const Ptr buf, unsigned long count)
{
    unsigned short  *endBuffer;
    unsigned short  *startBuffer = (unsigned short *)buf;
    unsigned short  saveShort;
    long            i;
 
    endBuffer = (unsigned short *)(buf + count) - 1;
    for (i = (count / (sizeof (short) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
        saveShort = *endBuffer;
        *endBuffer-- = *startBuffer;
        *startBuffer++ = saveShort;
    }
}
 
void ReverseMono16BitBuffer (const Ptr buf, unsigned long count)
{
    unsigned short  *endBuffer;
    unsigned short  *startBuffer = (unsigned short *)buf;
    unsigned short  saveShort;
    long            i;
 
    endBuffer = (unsigned short *)(buf + count) - 1;
    for (i = (count / (sizeof (short) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
        saveShort = *endBuffer;
        *endBuffer-- = *startBuffer;
        *startBuffer++ = saveShort;
    }
}
 
void ReverseStereo16BitBuffer (const Ptr buf, unsigned long count)
{
    unsigned long   *endBuffer;
    unsigned long   *startBuffer = (unsigned long *)buf;
    unsigned long   saveLong;
    long            i;
 
    endBuffer = (unsigned long *)(buf + count) - 1;
    for (i = (count / (sizeof (long) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
        saveLong = *endBuffer;
        *endBuffer-- = *startBuffer;
        *startBuffer++ = saveLong;
    }
}