view src/cdrom/macosx/AudioFilePlayer.h @ 914:bbf8dcc8aed6

Date: Wed, 23 Jun 2004 17:05:33 -0400 From: Chris Nelson Subject: [SDL] [Patch] WiseGroup MP-8800 / MP-8866 (PS2 Joystick) In the current cvs version, SDL doesn't handle these Playstation2 controller => USB adapters correctly, in linux. It will always assume that the maximum number of joysticks (2 in the case of the MP-8866, 4 in the case of the 8800) are plugged in. This is bad not only because it allows SDL to exaggerate the number of logical joysticks, but primarily because the joystick axes are mapped incorrectly, all over the place, such that the devices are effectively unusable unless you have the maximum number of joysticks plugged in. My changes to src/joystick/linux/SDL_sysjoystick.c build on another's previous work (which was a special case for this very joystick, actually), and fix both of these problems, as well as making the current code a little more general, to allow for others to more easily drop in code for quirky joysticks such as these. I've tested this code under 2.6.7 as well as 2.4.24... Both work as advertised (provided you load the JOYDEV linux code as a module, otherwise they won't work at all, new code or old, but that's another issue entirely). Though this sounds horribly formal, you have my permission to distribute all of my work on this issue under the LGPL. So there.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 25 Jul 2004 18:31:50 +0000
parents b8d311d90021
children f8d5ddc7aef1
line wrap: on
line source

/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2004 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org

    This file based on Apple sample code. We haven't changed the file name, 
    so if you want to see the original search for it on apple.com/developer
*/

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  AudioFilePlayer.h
//
#ifndef __AudioFilePlayer_H__
#define __AudioFilePlayer_H__

#include <CoreServices/CoreServices.h>

#include <AudioToolbox/AudioConverter.h>
#include <AudioUnit/AudioUnit.h>

#include "SDL_error.h"

const char* AudioFilePlayerErrorStr (OSStatus error);

void ThrowResult (OSStatus result, const char *str);

#define THROW_RESULT(str)                                       \
    if (result) {                                               \
        ThrowResult (result, str);                              \
    }

typedef void (*AudioFilePlayNotifier)(void          *inRefCon,
                                    OSStatus        inStatus);

enum {
    kAudioFilePlayErr_FilePlayUnderrun = -10000,
    kAudioFilePlay_FileIsFinished = -10001,
    kAudioFilePlay_PlayerIsUninitialized = -10002
};


class AudioFileManager;

#pragma mark __________ AudioFilePlayer
class AudioFilePlayer
{
public:
    AudioFilePlayer (const FSRef    *inFileRef);
    
    ~AudioFilePlayer();

    void            SetDestination (AudioUnit                   &inDestUnit, 
                                int                             inBusNumber);
    
    void            SetNotifier (AudioFilePlayNotifier inNotifier, void *inRefCon)
    {
        mNotifier = inNotifier;
        mRefCon = inRefCon;
    }
    
    void            SetStartFrame (int frame); // seek in the file
    
    int             GetCurrentFrame (); // get the current frame position
    
    void            SetStopFrame (int frame);   // set limit in the file
    
    void            Connect();
    
    void            Disconnect();

    void            DoNotification (OSStatus inError) const;
    
    bool            IsConnected () const { return mConnected; }

    UInt32          GetBusNumber () const { return mBusNumber; }
    
    AudioUnit       GetDestUnit () const { return mPlayUnit; }
    
    AudioConverterRef   GetAudioConverter() const { return mConverter; }

#if DEBUG    
    void            Print() const 
    {
        printf ("Destination Bus:%ld\n", GetBusNumber());
        printf ("Is Connected:%s\n", (IsConnected() ? "true" : "false"));
        printf ("- - - - - - - - - - - - - - \n");
    }
#endif

    const AudioStreamBasicDescription&      GetFileFormat() const { return mFileDescription; }
    
private:
    AudioUnit                       mPlayUnit;
    UInt32                          mBusNumber;
    SInt16                          mForkRefNum;
    
    AudioUnitInputCallback          mInputCallback;

    AudioStreamBasicDescription     mFileDescription;
    
    bool                            mConnected;
    
    AudioFileManager*               mAudioFileManager;
    AudioConverterRef               mConverter;
    
    AudioFilePlayNotifier           mNotifier;
    void*                           mRefCon;
    
    int                             mStartFrame;
    
#pragma mark __________ Private_Methods
    
    void        OpenFile (const FSRef *inRef, SInt64& outFileSize);
};

#pragma mark __________ AudioFileManager
class AudioFileManager
{
public:
    AudioFileManager (AudioFilePlayer &inParent, 
                      SInt16          inForkRefNum, 
                      SInt64          inFileLength,
                      UInt32          inChunkSize);
    
    ~AudioFileManager();
    
    
    void                Connect (AudioConverterRef inConverter) 
    {
        mParentConverter = inConverter;
        DoConnect();
    }

        // this method should NOT be called by an object of this class
        // as it is called by the parent's Disconnect() method
    void                Disconnect ();

    OSStatus            Read(char *buffer, UInt32 *len);

    const char*         GetFileBuffer () { return mFileBuffer; }

    const AudioFilePlayer&  GetParent () const { return mParent; }
    
    void                SetPosition (SInt64 pos);  // seek/rewind in the file
    
    int                 GetByteCounter () { return mByteCounter; } // return actual bytes streamed to audio hardware
    
    void                SetEndOfFile (SInt64 pos);  // set the "EOF" (will behave just like it reached eof)
   
protected:
    AudioFilePlayer&    mParent;
    AudioConverterRef   mParentConverter;
    SInt16              mForkRefNum;
    SInt64              mAudioDataOffset;
    
    char*               mFileBuffer;

    int                 mByteCounter;

    bool                mReadFromFirstBuffer;
    bool                mLockUnsuccessful;
    bool                mIsEngaged;
    
    int                 mNumTimesAskedSinceFinished;

public:
    const UInt32        mChunkSize;
    SInt64              mFileLength;
    SInt64              mReadFilePosition;
    bool                mWriteToFirstBuffer;
    bool                mFinishedReadingData;

protected:
    OSStatus            Render (AudioBuffer &ioData);
    
    OSStatus            GetFileData (void** inOutData, UInt32 *inOutDataSize);
    
    void                DoConnect ();
        
    void                AfterRender ();

public:
    static OSStatus     FileInputProc (void                             *inRefCon, 
                                        AudioUnitRenderActionFlags      inActionFlags,
                                        const AudioTimeStamp            *inTimeStamp, 
                                        UInt32                          inBusNumber, 
                                        AudioBuffer                     *ioData);
    static OSStatus     ACInputProc (AudioConverterRef          inAudioConverter,
                                            UInt32*                     outDataSize,
                                            void**                      outData,
                                            void*                       inUserData);
};


#endif