Logo Search packages:      
Sourcecode: sarien version File versions  Download package

sound_ahi.c

/*  Sarien - A Sierra AGI resource interpreter engine
 *  Copyright (C) 1999,2001 Stuart George and Claudio Matsuoka
 *  
 *  $Id: sound_ahi.c,v 1.5 2001/09/03 01:26:26 cmatsuoka Exp $
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; see docs/COPYING for further details.
 */

/*
 * Amiga sound driver by Paul Hill <paul@lagernet.clara.co.uk>
 * Based on the BSD sound driver by Claudio Matsuoka <claudio@helllabs.org>
 * and the Basilisk II Amiga AHI audio driver by Christian Bauer
 */

#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/ahi.h>
#include <proto/exec.h>
#include <proto/ahi.h>
#include <proto/dos.h>
#include <proto/alib.h>

#include "sarien.h"
#include "sound.h"

static int ahi_init_sound (SINT16 *b);
void ahi_close_sound();

static struct sound_driver sound_ahi = {
      "amiga /dev/audio sound output",
      ahi_init_sound,
      ahi_close_sound,
};

struct Library      *AHIBase = NULL;
struct MsgPort      *AHImp     = NULL;
struct AHIRequest   *AHIio     = NULL;
BYTE                 AHIDevice = -1;

/* Global variables */
static ULONG ahi_id = AHI_DEFAULT_ID;           /* AHI audio ID */
static struct AHIAudioCtrl *ahi_ctrl = NULL;
static struct AHISampleInfo sample[2];          /* For double-buffering */
static struct Hook sf_hook;
static int play_buf = 0;            /* Number of currently played buffer */

/* Prototypes */
static __saveds __attribute__((regparm(3)))ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/);

static SINT16 *buffer;

/*
 *  Initialization
 */

int AudioInit(void)
{
//    int audio_frames_per_block;
      printf("** AudioInit()\n");
      sample[0].ahisi_Address = sample[1].ahisi_Address = NULL;

      // Sound disabled in prefs? Then do nothing
      //    if (PrefsFindBool("nosound")) return 0;

      // AHI available?
      if (AHIBase == NULL)
      {
            printf("No AHI!\n");
            return 0;
      }

      // Initialize callback hook
      sf_hook.h_Entry = (HOOKFUNC)audio_callback;

      // Read "sound" preferences
      //    const char *str = PrefsFindString("sound");
      //    if (str)
      //          sscanf(str, "ahi/%08lx", &ahi_id);

      // Open audio control structure
      if ((ahi_ctrl = AHI_AllocAudio(
            AHIA_AudioID, ahi_id,
            AHIA_Channels, 1,
            AHIA_Sounds, 2,
            AHIA_SoundFunc, (ULONG)&sf_hook,
            TAG_END)) == NULL) {
            printf("No AHI control!\n");
            return 0;
      }

      // Prepare SampleInfos and load sounds (two sounds for double buffering)
      sample[0].ahisi_Type = AHIST_M16S;
      sample[0].ahisi_Length = BUFFER_SIZE;
      sample[0].ahisi_Address = AllocVec(BUFFER_SIZE * 2, MEMF_PUBLIC | MEMF_CLEAR);
      sample[1].ahisi_Type = AHIST_M16S;
      sample[1].ahisi_Length = BUFFER_SIZE;
      sample[1].ahisi_Address = AllocVec(BUFFER_SIZE * 2, MEMF_PUBLIC | MEMF_CLEAR);
      if (sample[0].ahisi_Address == NULL || sample[1].ahisi_Address == NULL) return 0;
      AHI_LoadSound(0, AHIST_DYNAMICSAMPLE, &sample[0], ahi_ctrl);
      AHI_LoadSound(1, AHIST_DYNAMICSAMPLE, &sample[1], ahi_ctrl);

      // Set parameters
      play_buf = 0;
      AHI_SetVol(0, 0x10000, 0x8000, ahi_ctrl, AHISF_IMM);
      AHI_SetFreq(0, 22050, ahi_ctrl, AHISF_IMM);
      AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, AHISF_IMM);

      // Everything OK
      return 1;
}


/*
 *  Deinitialization
 */

void AudioExit(void)
{
      // Free everything
      if (ahi_ctrl)
      {
            AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END);
            AHI_FreeAudio(ahi_ctrl);
            ahi_ctrl = NULL;
      }

      if (sample[0].ahisi_Address)
      {
            FreeVec(sample[0].ahisi_Address);
            sample[0].ahisi_Address = NULL;
      }
      if (sample[1].ahisi_Address)
      {
            FreeVec(sample[1].ahisi_Address);
            sample[1].ahisi_Address = NULL;
      }
}


/*
 *  AHI sound callback, request next buffer
 */

static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/)
{
      play_buf ^= 1;

      memcpy(sample[play_buf].ahisi_Address, buffer, BUFFER_SIZE * 2);

      // Play next buffer
      AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, 0);

      // Mix the next buffer...
      play_sound ();
      mix_sound ();

      return 0;
}


BOOL OpenAHI(void)
{
      if ((AHImp = CreateMsgPort()))
      {
            if ((AHIio = (struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))))
            {
                  AHIio->ahir_Version = 4;
                  if(!(AHIDevice = OpenDevice(AHINAME, AHI_NO_UNIT, (struct IORequest *) AHIio,NULL))) {
                        AHIBase = (struct Library *) AHIio->ahir_Std.io_Device;
                        return TRUE;
                  }
            }
       }
      return FALSE;
}


void CloseAHI(void)
{
      if(!AHIDevice) CloseDevice((struct IORequest *)AHIio);
      AHIDevice = -1;

      if (AHIio) DeleteIORequest((struct IORequest *)AHIio);
      AHIio = NULL;

      if (AHImp) DeleteMsgPort(AHImp);
      AHImp = NULL;
}

void __init_sound ()
{
      snd = &sound_ahi;
}


static int ahi_init_sound (SINT16 *b)
{
      buffer = b;
      printf("** ahi_init_sound()\n");

      report ("Amiga sound driver written by Paul Hill\n");

      if (OpenAHI())
      {
            printf("** AHI open\n");
            if (AudioInit())
            {
                  printf("** starting audio\n");
                  AHI_ControlAudio(ahi_ctrl, AHIC_Play, TRUE, TAG_END);

                  return err_OK;
            }
            report ("sound_ahi: error initialising audio\n");
            return err_Unk;
      }
      report ("sound_ahi: error initialising AHI\n");
      return err_Unk;
}


void ahi_close_sound()
{
      printf("** ahi_close_sound()\n");

      Delay(10);
      AudioExit();
      Delay(10);
      CloseAHI();
}


Generated by  Doxygen 1.6.0   Back to index