Browse Source

Remove old buggy sound code, and start a fresh new APU module. (empty for now)

Godzil 6 years ago
parent
commit
f6d0c8d93a
7 changed files with 40 additions and 1598 deletions
  1. 1 2
      src/apu/CMakeLists.txt
  2. 0 434
      src/apu/SndAlleg.c
  3. 0 556
      src/apu/SndUnixT.c
  4. 0 504
      src/apu/Sound.c
  5. 10 0
      src/apu/apu.c
  6. 14 0
      src/include/apu/apu.h
  7. 15 102
      src/main.c

+ 1 - 2
src/apu/CMakeLists.txt

@@ -9,6 +9,5 @@
 # $HeadURL$
 # $Revision$
 
-add_library(apu SndUnixT.c Sound.c)
-#add_library(apu SndAlleg.c Sound.c)
+add_library(apu apu.c apu.c)
 target_link_libraries(apu portaudio_static)

+ 0 - 434
src/apu/SndAlleg.c

@@ -1,434 +0,0 @@
-/*
- *  Allegro Sound Driver for EMULib Sound system - The peTI-NESulator Project
- *  SndAlleg.C
- *
- *  Created by Manoel Trapier
- *  Copyright 2003-2008 986 Corp. All rights reserved.
- *
- *  $LastChangedDate$
- *  $Author$
- *  $HeadURL$
- *  $Revision$
- *
- */
-#include <Sound.h>
-
-/* Allegro includes */
-#ifdef __APPLE__
-#define USE_CONSOLE
-#include <Allegro/allegro.h>
-#else
-#define USE_CONSOLE
-#include <allegro.h>
-#endif
-
-#include <os_dependent.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-//#include <unistd.h>
-//#include <fcntl.h>
-#include <pthread.h>
-//#include <sys/ioctl.h>
-    
-#define AUDIO_CONV(A) (128+(A))
-
-
-AUDIOSTREAM *stream;
-
-static pthread_t ThreadID;
-static int SoundRate    = 0;
-static int MasterVolume = 64;
-static int MasterSwitch = (1<<SND_CHANNELS)-1;
-static int LoopFreq     = 25;
-static int NoiseGen     = 1;
-static int Suspended    = 0;
-static int SoundRun     = 0;
-static struct
-{
-  int Type;                       /* Channel type (SND_*)             */
-  int Freq;                       /* Channel frequency (Hz)           */
-  int Volume;                     /* Channel volume (0..255)          */
-
-  const signed char *Data;              /* Wave data (-128..127 each)       */
-  int Length;                     /* Wave length in Data              */
-  int Rate;                       /* Wave playback rate (or 0Hz)      */
-  int Pos;                        /* Wave current position in Data    */  
-
-  int Count;                      /* Phase counter                    */
-} CH[SND_CHANNELS];
-
-static void UnixSetWave(int Channel,const signed char *Data,int Length,int Rate);
-static void UnixSetSound(int Channel,int NewType);
-static void UnixDrum(int Type,int Force);
-static void UnixSetChannels(int Volume,int Switch);
-static void UnixSound(int Channel,int NewFreq,int NewVolume);
-
-static int  OpenSoundDevice(int Rate,int Verbose);
-static void *DSPLoop(void *Arg);
-
-/** StopSound() **********************************************/
-/** Temporarily suspend sound.                              **/
-/*************************************************************/
-void StopSound(void) { Suspended=1; }
-
-/** ResumeSound() ********************************************/
-/** Resume sound after StopSound().                         **/
-/*************************************************************/
-void ResumeSound(void) { Suspended=0; }
-
-/** OpenSoundDevice() ****************************************/
-/** Open /dev/dsp with a given level of sound quality.      **/
-/** Returns 0 if failed or sound quality (Mode).            **/
-/*************************************************************/
-static int OpenSoundDevice(int Rate,int Verbose)
-{
-  voice_start(stream->voice);
-  
-  if(Verbose) puts("OK");
-  return(Rate);
-}
-
-/** DSPLoop() ************************************************/
-/** Main loop of the sound server.                          **/
-/*************************************************************/
-static void *DSPLoop(void *Arg)
-{
-  int Wave[SND_BUFSIZE];
-  unsigned char *Buf;
-  register int J,I,K,L,M,N,L1,L2,A1,A2,V;
-  int FreqCount;
-   N = L = A2 = 0;
-
-  for(J=0;J<SND_CHANNELS;J++)
-  {
-    CH[J].Type   = SND_MELODIC;
-    CH[J].Count  = 0;
-    CH[J].Volume = 0;
-    CH[J].Freq   = 0;
-  }
-
-
-
-  FreqCount=SoundRate/SND_BUFSIZE;
-
-  for(;;)
-  {
-    Buf = get_audio_stream_buffer(stream);
-
-      if (Buf) {
-      FreqCount-=LoopFreq;
-      
-    /* If suspending sound... */
-    if(Suspended)
-    {
-      /* Close sound device */
-      while(Suspended) sleep(1);
-      /* Reopen sound device */
-      SoundRate=OpenSoundDevice(SoundRate,0);
-    }
-
-    /* Waveform generator */
-    for(J=0,M=MasterSwitch;M&&(J<SND_CHANNELS);J++,M>>=1)
-      if(CH[J].Freq&&(V=CH[J].Volume)&&(M&1))
-        switch(CH[J].Type)
-        {
-          case SND_NOISE: /* White Noise */
-            /* For high frequencies, recompute volume */
-            if(CH[J].Freq<=SoundRate) K=0x10000*CH[J].Freq/SoundRate;
-            else { V=V*SoundRate/CH[J].Freq;K=0x10000; }
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L1+=K;
-              if(L1&0xFFFF0000)
-              {
-                L1&=0xFFFF;
-                if((NoiseGen<<=1)&0x80000000) NoiseGen^=0x08000001;
-              }
-              Wave[I]+=NoiseGen&1? V:-V;
-            }
-            CH[J].Count=L1;
-            break;
-
-          case SND_WAVE: /* Custom Waveform */
-            /* Waveform data must have correct length! */
-            if(CH[J].Length<=0) break;
-            /* Start counting */
-            K  = CH[J].Rate>0? (SoundRate<<15)/CH[J].Freq/CH[J].Rate
-                             : (SoundRate<<15)/CH[J].Freq/CH[J].Length;
-            L1 = CH[J].Pos%CH[J].Length;
-            L2 = CH[J].Count;
-            A1 = CH[J].Data[L1]*V;
-            /* If expecting interpolation... */
-            if(L2<K)
-            {
-              /* Compute interpolation parameters */
-              A2 = CH[J].Data[(L1+1)%CH[J].Length]*V;
-              L  = (L2>>15)+1;
-              N  = ((K-(L2&0x7FFF))>>15)+1;
-            }
-            /* Add waveform to the buffer */
-            for(I=0;I<SND_BUFSIZE;I++)
-              if(L2<K)
-              {
-                /* Interpolate linearly */
-                Wave[I]+=A1+L*(A2-A1)/N;
-                /* Next waveform step */
-                L2+=0x8000;
-                /* Next interpolation step */
-                L++;
-              }
-              else
-              {
-                L1 = (L1+L2/K)%CH[J].Length;
-                L2 = (L2%K)+0x8000;
-                A1 = CH[J].Data[L1]*V;
-                Wave[I]+=A1;
-                /* If expecting interpolation... */
-                if(L2<K)
-                {
-                  /* Compute interpolation parameters */
-                  A2 = CH[J].Data[(L1+1)%CH[J].Length]*V;
-                  L  = 1;
-                  N  = ((K-L2)>>15)+1;
-                }
-              }
-            /* End counting */
-            CH[J].Pos   = L1;
-            CH[J].Count = L2;
-            break;
- 
- 
-          case SND_QS_DU0:
-             /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0x2000?(L2&0x8000? V:0):(L2&0x8000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_QS_DU1:
-       /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0x4000?(L2&0x8000? V:0):(L2&0x8000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_QS_DU3:
-       /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0xC000?(L2&0x4000? V:0):(L2&0xC000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_QS_DU2:
-          case SND_MELODIC: /* Melodic Sound */         
-          default:          /* Default Sound */
-            /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0x8000? (L2&0x8000? V:0):(L2&0x8000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-              
-          case SND_TRIANGLE:          /* Default Sound */
-            /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+= L1&0x8000?V:-V /*(L2&0x8000? V:0):(L2&0x8000? 0:-V)*/;
-              L1=L2;
-            
-            
-            }
-            CH[J].Count=L1;
-            break;
-        }
-
-    /* Mix and convert waveforms */
-    for(J=0;J<SND_BUFSIZE;J++)
-    {
-      I=(Wave[J]*MasterVolume)>>16;
-      I=I<-128? -128:I>127? 127:I;
-      Buf[J]=AUDIO_CONV(I);
-      Wave[J]=0;
-    }
-    free_audio_stream_buffer(stream);
-    }
-  }
-
-  return(0);
-}
-
-/** InitSound() **********************************************/
-/** Initialize DSP. Returns Rate on success, 0 otherwise.   **/
-/** Mode is 0 to skip initialization (will be silent).      **/
-/*************************************************************/
-int InitSound(int Rate,int Verbose)
-{
-  /* If sound was initialized, kill it */
-  TrashSound();
-
-  /* Silence requested */
-  if(Rate<=0) return(0);
-
-  /* Synthesis rate should be at least 8kHz */
-  if(Rate<8192) Rate=44100;
-
-  /* Initialize things */
-  SoundRate = 0;
-  ThreadID  = 0;
-  Suspended = 0;
-
-  /* Set driver functions */
-  SndDriver.SetSound    = UnixSetSound;
-  SndDriver.Drum        = UnixDrum;
-  SndDriver.SetChannels = UnixSetChannels;
-  SndDriver.Sound       = UnixSound;
-  SndDriver.SetWave     = UnixSetWave;
-
-  if (install_sound(DIGI_AUTODETECT, MIDI_NONE, "") != 0)
-  {
-      console_printf(Console_Error, "%s!\n", allegro_error);
-      return 1;
-  }
-
-
-  stream = play_audio_stream(SND_BUFSIZE, 8, FALSE, Rate, 255, 128);
-  if (!stream) {
-      console_printf(Console_Error, "Error creating audio stream!\n");
-      return 1;
-  }
-
-  voice_stop(stream->voice);
-
-  /* Open sound device */
-  if(Verbose) puts("Starting sound server:");
-  if(!(Rate=OpenSoundDevice(Rate,Verbose))) return(0);
-
-  /* Create DSPLoop() thread */
-  if(Verbose) console_printf(Console_Default, "  Creating thread...");
-  if(pthread_create(&ThreadID,0,DSPLoop,0))
-  { if(Verbose) puts("FAILED");return(0); }
-
-  /* Detach the thread */
-  pthread_detach(ThreadID);
-
-  /* Done */
-  SoundRun = 1;
-  if(Verbose) puts("OK");
-  return(SoundRate=Rate);
-}
-
-/** TrashSound() *********************************************/
-/** Shut DSP down.                                          **/
-/*************************************************************/
-void TrashSound(void)
-{
-  if (SoundRun == 1)
-  {
-     StopSound();
-     console_printf(Console_Default, "%s: Kill thread...\n", __func__);
-     if(ThreadID)    pthread_cancel(ThreadID);
-  }
-  SoundRun = 0;
-  SoundRate = 0;
-  ThreadID  = 0;
-}
-
-/** UnixSound() **********************************************/
-/** Generate sound of given frequency (Hz) and volume       **/
-/** (0..255) via given channel.                             **/
-/*************************************************************/
-void UnixSound(int Channel,int NewFreq,int NewVolume)
-{
-  if((Channel<0)||(Channel>=SND_CHANNELS)) return;
-  if(!NewVolume||!NewFreq) { NewVolume=0;NewFreq=0; }
-
-  CH[Channel].Volume = NewVolume;
-  CH[Channel].Freq   = NewFreq;
-}
-
-/** UnixSetChannels() ****************************************/
-/** Set master volume (0..255) and turn channels on/off.    **/
-/** Each bit in Toggle corresponds to a channel (1=on).     **/
-/*************************************************************/
-void UnixSetChannels(int MVolume,int MSwitch)
-{
-  /* Set new MasterSwitch value */
-  MasterSwitch = MSwitch;
-  MasterVolume = MVolume;
-}
-
-/** UnixSetSound() *******************************************/
-/** Set sound type (SND_NOISE/SND_MELODIC) for a given      **/
-/** channel.                                                **/
-/*************************************************************/
-void UnixSetSound(int Channel,int NewType)
-{
-  if((Channel<0)||(Channel>=SND_CHANNELS)) return;
-  CH[Channel].Type = NewType;
-}
-
-
-/** UnixSetWave() ********************************************/
-/** Set waveform for a given channel. The channel will be   **/
-/** marked with sound type SND_WAVE. Set Rate=0 if you want **/
-/** waveform to be an instrument or set it to the waveform  **/
-/** own playback rate.                                      **/
-/*************************************************************/
-void UnixSetWave(int Channel,const signed char *Data,int Length,int Rate)
-{
-  if((Channel<0)||(Channel>=SND_CHANNELS)||(Length<=0)) return;
-
-  CH[Channel].Type   = SND_WAVE;
-  CH[Channel].Length = Length;
-  CH[Channel].Rate   = Rate;
-  CH[Channel].Pos    = 0;
-  CH[Channel].Count  = 0;
-  CH[Channel].Data   = Data;
-}
-
-/** UnixDrum() ***********************************************/
-/** Hit a drum of a given type with given force.            **/
-/*************************************************************/
-void UnixDrum(int Type,int Force)
-{
-  /* This function is currently empty */
-}

+ 0 - 556
src/apu/SndUnixT.c

@@ -1,556 +0,0 @@
-/** EMULib Emulation Library *********************************/
-/**                                                         **/
-/**                         SndUnix.c                       **/
-/**                                                         **/
-/** This file contains standard sound generation routines   **/
-/** for Unix using /dev/dsp and /dev/audio.                 **/
-/**                                                         **/
-/** Copyright (C) Marat Fayzullin 1996-2002                 **/
-/**     You are not allowed to distribute this software     **/
-/**     commercially. Please, notify me, if you make any    **/
-/**     changes to this file.                               **/
-/*************************************************************/
-//#include "Sound.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <sys/ioctl.h>
-
-#include <os_dependent.h>
-#if 0
-#ifdef SUN_AUDIO  
-
-#include <sys/audioio.h>
-#include <sys/conf.h>
-#include <stropts.h>
-
-#define AUDIO_CONV(A) (ULAW[0xFF&(128+(A))]) 
-
-static unsigned char ULAW[256] =
-{
-    31,   31,   31,   32,   32,   32,   32,   33,
-    33,   33,   33,   34,   34,   34,   34,   35,
-    35,   35,   35,   36,   36,   36,   36,   37,
-    37,   37,   37,   38,   38,   38,   38,   39,
-    39,   39,   39,   40,   40,   40,   40,   41,
-    41,   41,   41,   42,   42,   42,   42,   43,
-    43,   43,   43,   44,   44,   44,   44,   45,
-    45,   45,   45,   46,   46,   46,   46,   47,
-    47,   47,   47,   48,   48,   49,   49,   50,
-    50,   51,   51,   52,   52,   53,   53,   54,
-    54,   55,   55,   56,   56,   57,   57,   58,
-    58,   59,   59,   60,   60,   61,   61,   62,
-    62,   63,   63,   64,   65,   66,   67,   68,
-    69,   70,   71,   72,   73,   74,   75,   76,
-    77,   78,   79,   81,   83,   85,   87,   89,
-    91,   93,   95,   99,  103,  107,  111,  119,
-   255,  247,  239,  235,  231,  227,  223,  221,
-   219,  217,  215,  213,  211,  209,  207,  206,
-   205,  204,  203,  202,  201,  200,  199,  198,
-   219,  217,  215,  213,  211,  209,  207,  206,
-   205,  204,  203,  202,  201,  200,  199,  198,
-   197,  196,  195,  194,  193,  192,  191,  191,
-   190,  190,  189,  189,  188,  188,  187,  187,
-   186,  186,  185,  185,  184,  184,  183,  183,
-   182,  182,  181,  181,  180,  180,  179,  179,
-   178,  178,  177,  177,  176,  176,  175,  175,
-   175,  175,  174,  174,  174,  174,  173,  173,
-   173,  173,  172,  172,  172,  172,  171,  171,
-   171,  171,  170,  170,  170,  170,  169,  169,
-   169,  169,  168,  168,  168,  168,  167,  167,
-   167,  167,  166,  166,  166,  166,  165,  165,
-   165,  165,  164,  164,  164,  164,  163,  163
-};
-
-#else /* SUN_AUDIO */
-
-#ifdef __FreeBSD__
-#include <machine/soundcard.h>
-#endif
- 
-#ifdef __NetBSD__
-#include <soundcard.h>
-#endif
- 
-#ifdef __linux__
-#include <sys/soundcard.h>
-#endif
-    
-#define AUDIO_CONV(A) (128+(A))
-
-#endif /* SUN_AUDIO */
-
-static pthread_t ThreadID;
-static int SoundFD;
-static int SoundRate    = 0;
-static int MasterVolume = 64;
-static int MasterSwitch = (1<<SND_CHANNELS)-1;
-static int LoopFreq     = 25;
-static int NoiseGen     = 1;
-static int Suspended    = 0;
-
-static struct
-{
-  int Type;                       /* Channel type (SND_*)             */
-  int Freq;                       /* Channel frequency (Hz)           */
-  int Volume;                     /* Channel volume (0..255)          */
-
-  signed char *Data;              /* Wave data (-128..127 each)       */
-  int Length;                     /* Wave length in Data              */
-  int Rate;                       /* Wave playback rate (or 0Hz)      */
-  int Pos;                        /* Wave current position in Data    */  
-
-  int Count;                      /* Phase counter                    */
-} CH[SND_CHANNELS];
-
-static void UnixSetWave(int Channel, signed char *Data,int Length,int Freq);
-static void UnixSetSound(int Channel,int NewType);
-static void UnixDrum(int Type,int Force);
-static void UnixSetChannels(int Volume,int Switch);
-static void UnixSound(int Channel,int NewFreq,int NewVolume);
-
-static int  OpenSoundDevice(int Rate,int Verbose);
-static void *DSPLoop(void *Arg);
-
-/** StopSound() **********************************************/
-/** Temporarily suspend sound.                              **/
-/*************************************************************/
-void StopSound(void) { Suspended=1; }
-
-/** ResumeSound() ********************************************/
-/** Resume sound after StopSound().                         **/
-/*************************************************************/
-void ResumeSound(void) { Suspended=0; }
-
-/** OpenSoundDevice() ****************************************/
-/** Open /dev/dsp with a given level of sound quality.      **/
-/** Returns 0 if failed or sound quality (Mode).            **/
-/*************************************************************/
-static int OpenSoundDevice(int Rate,int Verbose)
-{
-  int I,J,K;
-
-#ifdef SUN_AUDIO
-
-  if(Verbose) console_printf(Console_Default, "  Opening /dev/audio...");
-  if((SoundFD=open("/dev/audio",O_WRONLY | O_NONBLOCK))==-1)
-  {
-    if(Verbose) puts("FAILED");
-    return(0);
-  }
-
-  /*
-  ** Sun's specific initialization should be here...
-  ** We assume, that it's set to 8000Hz u-law mono right now.
-  */    
-
-#else /* SUN_AUDIO */
-
-  /* At first, we need to open /dev/dsp: */
-  if(Verbose) console_printf(Console_Default, "  Opening /dev/dsp...");
-  I=((SoundFD=open("/dev/dsp",O_WRONLY))<0);
-
-  /* Set 8-bit sound */
-  if(!I)
-  { 
-    if(Verbose) console_printf(Console_Default, "OK\n  Setting mode: 8bit...");
-    J=AFMT_U8;
-    I=(ioctl(SoundFD,SNDCTL_DSP_SETFMT,&J)<0);
-  }
-
-  /* Set mono sound */
-  if(!I)
-  {
-    if(Verbose) console_printf(Console_Default, "mono...");
-    J=0;
-    I=(ioctl(SoundFD,SNDCTL_DSP_STEREO,&J)<0);
-  }
-
-  /* Set sampling rate */
-  if(!I)
-  {
-    if(Verbose) console_printf(Console_Default, "OK\n  Setting sampling rate: %dHz...",Rate);
-    I=(ioctl(SoundFD,SNDCTL_DSP_SPEED,&Rate)<0);
-    if(Verbose) console_printf(Console_Default, "(got %dHz)...",Rate);
-  } 
-
-  /* Here we set the number of buffers to use */
-  if(!I)
-  { 
-    if(Verbose)
-      printf
-      (
-        "OK\n  Adjusting buffers: %d buffers %d bytes each...",
-        SND_BUFFERS,1<<SND_BITS
-      );
-
-    /* Set buffer length and number of buffers */
-    J=K=SND_BITS|(SND_BUFFERS<<16);
-    I=(ioctl(SoundFD,SNDCTL_DSP_SETFRAGMENT,&J)<0);
-
-    /* Buffer length as n, not 2^n! */
-    if((J&0xFFFF)<16) J=(J&0xFFFF0000)|(1<<(J&0xFFFF));
-    K=(1<<SND_BITS)|(SND_BUFFERS<<16);
-
-    /* If something went wrong... */
-    if(J!=K)
-    {
-      if((J>>16)<SND_BUFFERS)       I=-1;
-      if((J&0xFFFF)!=(1<<SND_BITS)) I=-1;
-    }
-  } 
-
-  /* If something failed, fall out */
-  if(I) { if(Verbose) puts("FAILED");return(0); }
-    
-#endif /* SUN_AUDIO */
-    
-  if(Verbose) puts("OK");
-  return(Rate);
-}
-
-/** DSPLoop() ************************************************/
-/** Main loop of the sound server.                          **/
-/*************************************************************/
-static void *DSPLoop(void *Arg)
-{
-  int Wave[SND_BUFSIZE];
-  unsigned char Buf[SND_BUFSIZE];
-  register int J,I,K,L,M,N,L1,L2,A1,A2,V;
-  int FreqCount;
-  int ret;
-
-  L = N = A2 = 0;
-
-  for(J=0;J<SND_CHANNELS;J++)
-  {
-    CH[J].Type   = SND_MELODIC;
-    CH[J].Count  = 0;
-    CH[J].Volume = 0;
-    CH[J].Freq   = 0;
-  }
-
-  FreqCount=SoundRate/SND_BUFSIZE;
-  for(;;FreqCount-=LoopFreq)
-  {
-    /* If suspending sound... */
-    if(Suspended)
-    {
-      /* Close sound device */
-#ifndef SUN_AUDIO
-      ioctl(SoundFD,SNDCTL_DSP_RESET);
-#endif
-      close(SoundFD);
-      /* Suspend execution until Suspended=0 */
-      while(Suspended) sleep(1);
-      /* Reopen sound device */
-      SoundRate=OpenSoundDevice(SoundRate,0);
-    }
-
-    /* Waveform generator */
-    for(J=0,M=MasterSwitch;M&&(J<SND_CHANNELS);J++,M>>=1)
-      if(CH[J].Freq&&(V=CH[J].Volume)&&(M&1))
-        switch(CH[J].Type)
-        {
-          case SND_NOISE: /* White Noise */
-            /* For high frequencies, recompute volume */
-            if(CH[J].Freq<=SoundRate) K=0x10000*CH[J].Freq/SoundRate;
-            else { V=V*SoundRate/CH[J].Freq;K=0x10000; }
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L1+=K;
-              if(L1&0xFFFF0000)
-              {
-                L1&=0xFFFF;
-                if((NoiseGen<<=1)&0x80000000) NoiseGen^=0x08000001;
-              }
-              Wave[I]+=NoiseGen&1? V:-V;
-            }
-            CH[J].Count=L1;
-            break;
-
-          case SND_WAVE: /* Custom Waveform */
-            /* Waveform data must have correct length! */
-            if(CH[J].Length<=0) break;
-            /* Start counting */
-            K  = CH[J].Rate>0? (SoundRate<<15)/CH[J].Freq/CH[J].Rate
-                             : (SoundRate<<15)/CH[J].Freq/CH[J].Length;
-            L1 = CH[J].Pos%CH[J].Length;
-            L2 = CH[J].Count;
-            A1 = CH[J].Data[L1]*V;
-            /* If expecting interpolation... */
-            if(L2<K)
-            {
-              /* Compute interpolation parameters */
-              A2 = CH[J].Data[(L1+1)%CH[J].Length]*V;
-              L  = (L2>>15)+1;
-              N  = ((K-(L2&0x7FFF))>>15)+1;
-            }
-            /* Add waveform to the buffer */
-            for(I=0;I<SND_BUFSIZE;I++)
-              if(L2<K)
-              {
-                /* Interpolate linearly */
-                Wave[I]+=A1+L*(A2-A1)/N;
-                /* Next waveform step */
-                L2+=0x8000;
-                /* Next interpolation step */
-                L++;
-              }
-              else
-              {
-                L1 = (L1+L2/K)%CH[J].Length;
-                L2 = (L2%K)+0x8000;
-                A1 = CH[J].Data[L1]*V;
-                Wave[I]+=A1;
-                /* If expecting interpolation... */
-                if(L2<K)
-                {
-                  /* Compute interpolation parameters */
-                  A2 = CH[J].Data[(L1+1)%CH[J].Length]*V;
-                  L  = 1;
-                  N  = ((K-L2)>>15)+1;
-                }
-              }
-            /* End counting */
-            CH[J].Pos   = L1;
-            CH[J].Count = L2;
-            break;
- 
- 
-          case SND_QS_DU0:
-             /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0x2000?(L2&0x8000? V:0):(L2&0x8000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_QS_DU1:
-       /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0x4000?(L2&0x8000? V:0):(L2&0x8000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_QS_DU3:
-       /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0xC000?(L2&0x4000? V:0):(L2&0xC000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_QS_DU2:
-          case SND_MELODIC: /* Melodic Sound */         
-          default:          /* Default Sound */
-            /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+=L1&0x8000? (L2&0x8000? V:0):(L2&0x8000? 0:-V);
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-            
-          case SND_TRIANGLE:          /* Default Sound */
-            /* Do not allow frequencies that are too high */
-            if(CH[J].Freq>=SoundRate/3) break;
-            K=0x10000*CH[J].Freq/SoundRate;
-            L1=CH[J].Count;
-            V<<=7;
-            for(I=0;I<SND_BUFSIZE;I++)
-            {
-              L2=L1+K;
-              Wave[I]+= L1&0x2000?V:-V /*(L2&0x8000? V:0):(L2&0x8000? 0:-V)*/;
-              L1=L2;
-            }
-            CH[J].Count=L1;
-            break;
-        }
-
-    /* Mix and convert waveforms */
-    for(J=0;J<SND_BUFSIZE;J++)
-    {
-      I=(Wave[J]*MasterVolume)>>16;
-      I=I<-128? -128:I>127? 127:I;
-      Buf[J]=AUDIO_CONV(I);
-      Wave[J]=0;
-    }
-
-    if(SoundFD==-1) sleep(1);
-    else
-    {
-#ifdef SUN_AUDIO
-      /* Flush output first, don't care about return status. After this
-      ** write next buffer of audio data. This method produces a horrible 
-      ** click on each buffer :( Any ideas, how to fix this?
-      */
-      ioctl(SoundFD,AUDIO_DRAIN);
-      write(SoundFD,Buf,SND_BUFSIZE);
-#else
-      /* We'll block here until next DMA buffer becomes free. It happens 
-      ** once per (1<<SND_BITS)/SoundRate seconds.
-      */
-      ret = write(SoundFD,Buf,SND_BUFSIZE);
-#endif
-    }
-  }
-
-  return(0);
-}
-
-/** InitSound() **********************************************/
-/** Initialize DSP. Returns Rate on success, 0 otherwise.   **/
-/** Mode is 0 to skip initialization (will be silent).      **/
-/*************************************************************/
-int InitSound(int Rate,int Verbose)
-{
-  /* If sound was initialized, kill it */
-  TrashSound();
-
-  /* Silence requested */
-  if(Rate<=0) return(0);
-
-  /* Synthesis rate should be at least 8kHz */
-  if(Rate<8192) Rate=44100;
-
-  /* Initialize things */
-  SoundRate = 0;
-  SoundFD   = -1;
-  ThreadID  = 0;
-  Suspended = 0;
-
-  /* Set driver functions */
-  SndDriver.SetSound    = UnixSetSound;
-  SndDriver.Drum        = UnixDrum;
-  SndDriver.SetChannels = UnixSetChannels;
-  SndDriver.Sound       = UnixSound;
-  SndDriver.SetWave     = UnixSetWave;
-
-  /* Open sound device */
-  if(Verbose) puts("Starting sound server:");
-  if(!(Rate=OpenSoundDevice(Rate,Verbose))) return(0);
-
-  /* Create DSPLoop() thread */
-  if(Verbose) console_printf(Console_Default, "  Creating thread...");
-  if(pthread_create(&ThreadID,0,DSPLoop,0))
-  { if(Verbose) puts("FAILED");return(0); }
-
-  /* Detach the thread */
-  pthread_detach(ThreadID);
-
-  /* Done */
-  if(Verbose) puts("OK");
-  return(SoundRate=Rate);
-}
-
-/** TrashSound() *********************************************/
-/** Shut DSP down.                                          **/
-/*************************************************************/
-void TrashSound(void)
-{
-  StopSound();
-  console_printf(Console_Default, "%s: Kill thread...\n", __func__);
-  if(ThreadID)    pthread_cancel(ThreadID);
-  console_printf(Console_Default, "%s: close /dev/xxx ...\n", __func__);
-  if(SoundFD!=-1) close(SoundFD);
-
-  SoundRate = 0;
-  SoundFD   = -1;
-  ThreadID  = 0;
-}
-
-/** UnixSound() **********************************************/
-/** Generate sound of given frequency (Hz) and volume       **/
-/** (0..255) via given channel.                             **/
-/*************************************************************/
-void UnixSound(int Channel,int NewFreq,int NewVolume)
-{
-  if((Channel<0)||(Channel>=SND_CHANNELS)) return;
-  if(!NewVolume||!NewFreq) { NewVolume=0;NewFreq=0; }
-
-  CH[Channel].Volume = NewVolume;
-  CH[Channel].Freq   = NewFreq;
-}
-
-/** UnixSetChannels() ****************************************/
-/** Set master volume (0..255) and turn channels on/off.    **/
-/** Each bit in Toggle corresponds to a channel (1=on).     **/
-/*************************************************************/
-void UnixSetChannels(int MVolume,int MSwitch)
-{
-  /* Set new MasterSwitch value */
-  MasterSwitch = MSwitch;
-  MasterVolume = MVolume;
-}
-
-/** UnixSetSound() *******************************************/
-/** Set sound type (SND_NOISE/SND_MELODIC) for a given      **/
-/** channel.                                                **/
-/*************************************************************/
-void UnixSetSound(int Channel,int NewType)
-{
-  if((Channel<0)||(Channel>=SND_CHANNELS)) return;
-  CH[Channel].Type = NewType;
-}
-
-
-/** UnixSetWave() ********************************************/
-/** Set waveform for a given channel. The channel will be   **/
-/** marked with sound type SND_WAVE. Set Rate=0 if you want **/
-/** waveform to be an instrument or set it to the waveform  **/
-/** own playback rate.                                      **/
-/*************************************************************/
-void UnixSetWave(int Channel, signed char *Data, int Length, int Freq)
-{
-  if((Channel<0)||(Channel>=SND_CHANNELS)||(Length<=0)) return;
-
-  CH[Channel].Type   = SND_WAVE;
-  CH[Channel].Length = Length;
-  CH[Channel].Rate   = Freq;
-  CH[Channel].Pos    = 0;
-  CH[Channel].Count  = 0;
-  CH[Channel].Data   = Data;
-}
-
-/** UnixDrum() ***********************************************/
-/** Hit a drum of a given type with given force.            **/
-/*************************************************************/
-void UnixDrum(int Type,int Force)
-{
-  /* This function is currently empty */
-}
-#endif

+ 0 - 504
src/apu/Sound.c

@@ -1,504 +0,0 @@
-/** EMULib Emulation Library *********************************/
-/**                                                         **/
-/**                          Sound.c                        **/
-/**                                                         **/
-/** This file file implements core part of the sound API    **/
-/** and functions needed to log soundtrack into a MIDI      **/
-/** file. See Sound.h for declarations.                     **/
-/**                                                         **/
-/** Copyright (C) Marat Fayzullin 1996-2007                 **/
-/**     You are not allowed to distribute this software     **/
-/**     commercially. Please, notify me, if you make any    **/
-/**     changes to this file.                               **/
-/*************************************************************/
-/*
- *  $LastChangedDate$
- *  $Author$
- *  $HeadURL$
- *  $Revision$
- */
-
-#include "Sound.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#ifdef UNIX
-#include <unistd.h>
-#endif
-
-typedef unsigned char byte;
-typedef unsigned short word;
-
-struct SndDriverStruct SndDriver =
-{
-  (void (*)(int,int))0,
-  (void (*)(int,int))0,
-  (void (*)(int,int))0,
-  (void (*)(int,int,int))0,
-  (void (*)(int,signed char *,int,int))0,
-  (const signed char *(*)(int))0
-};
-
-static const struct { byte Note;word Wheel; } Freqs[4096] =
-{
-#include "MIDIFreq.h"
-};
-
-static const int Programs[5] =
-{
-  80,  /* SND_MELODIC/SND_RECTANGLE */
-  80,  /* SND_TRIANGLE */
-  122, /* SND_NOISE */
-  122, /* SND_PERIODIC */
-  80   /* SND_WAVE */
-};
-
-static struct
-{
-  int Type;
-  int Note;
-  int Pitch;
-  int Level;
-} CH[MIDI_CHANNELS] =
-{
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 },
-  { -1,-1,-1,-1 }
-};
-
-static const char *LogName  = 0;
-static int  Logging   = MIDI_OFF;
-static int  TickCount = 0;
-static int  LastMsg   = -1;
-static int  DrumOn    = 0;
-static FILE *MIDIOut  = 0;
-
-static void MIDISound(int Channel,int Freq,int Volume);
-static void MIDISetSound(int Channel,int Type);
-static void MIDIDrum(int Type,int Force);
-static void MIDIMessage(byte D0,byte D1,byte D2);
-static void NoteOn(byte Channel,byte Note,byte Level);
-static void NoteOff(byte Channel);
-static void WriteDelta(void);
-static void WriteTempo(int Freq);
-
-/** SHIFT() **************************************************/
-/** Make MIDI channel#10 last, as it is normally used for   **/
-/** percussion instruments only and doesn't sound nice.     **/
-/*************************************************************/
-#define SHIFT(Ch) (Ch==15? 9:Ch>8? Ch+1:Ch)
-
-/** Sound() **************************************************/
-/** Generate sound of given frequency (Hz) and volume       **/
-/** (0..255) via given channel. Setting Freq=0 or Volume=0  **/
-/** turns sound off.                                        **/
-/*************************************************************/
-void Sound(int Channel,int Freq,int Volume)
-{
-  if(Channel<0) return;
-  Freq   = Freq<0? 0:Freq;
-  Volume = Volume<0? 0:Volume>255? 255:Volume;
-
-  /* Call sound driver if present */
-  if(SndDriver.Sound) (*SndDriver.Sound)(Channel,Freq,Volume);
-
-  /* Log sound to MIDI file */
-  MIDISound(Channel,Freq,Volume);
-}
-
-/** Drum() ***************************************************/
-/** Hit a drum of given type with given force (0..255).     **/
-/** MIDI drums can be used by ORing their numbers with      **/
-/** SND_MIDI.                                               **/
-/*************************************************************/
-void Drum(int Type,int Force)
-{
-  Force = Force<0? 0:Force>255? 255:Force;
-
-  if(SndDriver.Drum) (*SndDriver.Drum)(Type,Force);
-
-  /* Log drum to MIDI file */
-  MIDIDrum(Type,Force);
-}
-
-/** SetSound() ***********************************************/
-/** Set sound type at a given channel. MIDI instruments can **/
-/** be set directly by ORing their numbers with SND_MIDI.   **/
-/*************************************************************/
-void SetSound(int Channel,int Type)
-{
-  if(Channel<0) return;
-
-  if(SndDriver.SetSound) (*SndDriver.SetSound)(Channel,Type);
-
-  /* Log instrument change to MIDI file */
-  MIDISetSound(Channel,Type);
-}
-
-/** SetChannels() ********************************************/
-/** Set master volume (0..255) and switch channels on/off.  **/
-/** Each channel N has corresponding bit 2^N in Switch. Set **/
-/** or reset this bit to turn the channel on or off.        **/ 
-/*************************************************************/
-void SetChannels(int Volume,int Switch)
-{
-  Volume = Volume<0? 0:Volume>255? 255:Volume;
-
-  if(SndDriver.SetChannels) (*SndDriver.SetChannels)(Volume,Switch);
-}
-
-/** SetWave() ************************************************/
-/** Set waveform for a given channel. The channel will be   **/
-/** marked with sound type SND_WAVE. Set Rate=0 if you want **/
-/** waveform to be an instrument or set it to the waveform  **/
-/** own playback rate.                                      **/
-/*************************************************************/
-void SetWave(int Channel,signed char *Data,int Length,int Rate)
-{
-  if((Channel<0)||(Length<=0)) return;
-
-  if(SndDriver.SetWave) (*SndDriver.SetWave)(Channel,Data,Length,Rate);
-
-  /* Log instrument change to MIDI file */
-  MIDISetSound(Channel,Rate? -1:SND_MELODIC);
-}
-
-/** GetWave() ************************************************/
-/** Get current read position for the buffer set with the   **/
-/** SetWave() call. Returns 0 if no buffer has been set, or **/
-/** if there is no playrate set (i.e. wave is instrument).  **/
-/*************************************************************/
-const signed char *GetWave(int Channel)
-{
-  return(SndDriver.GetWave? (*SndDriver.GetWave)(Channel):0);
-}
-
-/** InitMIDI() ***********************************************/
-/** Initialize soundtrack logging into MIDI file FileName.  **/
-/** Repeated calls to InitMIDI() will close current MIDI    **/
-/** file and continue logging into a new one.               **/ 
-/*************************************************************/
-void InitMIDI(const char *FileName)
-{
-  int WasLogging;
-
-  /* Must pass a name! */
-  if(!FileName) return;
-
-  /* Memorize logging status */
-  WasLogging=Logging;
-
-  /* If MIDI logging in progress, close current file */
-  if(MIDIOut) TrashMIDI();
-
-  /* Set log file name and ticks/second parameter, no logging yet */
-  LogName   = FileName;
-  Logging   = MIDI_OFF;
-  LastMsg   = -1;
-  TickCount = 0;
-  MIDIOut   = 0;
-  DrumOn    = 0;
-
-  /* If was logging, restart */
-  if(WasLogging) MIDILogging(MIDI_ON);
-}
-
-/** TrashMIDI() **********************************************/
-/** Finish logging soundtrack and close the MIDI file.      **/
-/*************************************************************/
-void TrashMIDI(void)
-{
-  long Length;
-  int J;
-
-  /* If not logging, drop out */
-  if(!MIDIOut) return;
-  /* Turn sound off */
-  for(J=0;J<MIDI_CHANNELS;J++) NoteOff(J);
-  /* End of track */
-  MIDIMessage(0xFF,0x2F,0x00);
-  /* Put track length in file */
-  fseek(MIDIOut,0,SEEK_END);
-  Length=ftell(MIDIOut)-22;
-  fseek(MIDIOut,18,SEEK_SET);
-  fputc((Length>>24)&0xFF,MIDIOut);
-  fputc((Length>>16)&0xFF,MIDIOut);
-  fputc((Length>>8)&0xFF,MIDIOut);
-  fputc(Length&0xFF,MIDIOut);
-
-  /* Done logging */
-  fclose(MIDIOut);
-  Logging   = MIDI_OFF;
-  LastMsg   = -1;
-  TickCount = 0;
-  MIDIOut   = 0;
-}
-
-/** MIDILogging() ********************************************/
-/** Turn soundtrack logging on/off and return its current   **/
-/** status. Possible values of Switch are MIDI_OFF (turn    **/
-/** logging off), MIDI_ON (turn logging on), MIDI_TOGGLE    **/
-/** (toggle logging), and MIDI_QUERY (just return current   **/
-/** state of logging).                                      **/
-/*************************************************************/
-int MIDILogging(int Switch)
-{
-  static const char MThd[] = "MThd\0\0\0\006\0\0\0\1";
-                           /* ID  DataLen   Fmt Trks */
-  static const char MTrk[] = "MTrk\0\0\0\0";
-                           /* ID  TrkLen   */
-  int J,I;
-
-  /* Toggle logging if requested */
-  if(Switch==MIDI_TOGGLE) Switch=!Logging;
-
-  if((Switch==MIDI_ON)||(Switch==MIDI_OFF))
-    if(Switch^Logging)
-    {
-      /* When turning logging off, silence all channels */
-      if(!Switch&&MIDIOut)
-        for(J=0;J<MIDI_CHANNELS;J++) NoteOff(J);
-
-      /* When turning logging on, open MIDI file */
-      if(Switch&&!MIDIOut&&LogName)
-      {
-        /* No messages have been sent yet */
-        LastMsg=-1;
-
-        /* Clear all storage */
-        for(J=0;J<MIDI_CHANNELS;J++)
-          CH[J].Note=CH[J].Pitch=CH[J].Level=-1;
-
-        /* Open new file and write out the header */
-        MIDIOut=fopen(LogName,"wb");
-        if(!MIDIOut) return(MIDI_OFF);
-        if(fwrite(MThd,1,12,MIDIOut)!=12)
-        { fclose(MIDIOut);MIDIOut=0;return(MIDI_OFF); }
-        fputc((MIDI_DIVISIONS>>8)&0xFF,MIDIOut);
-        fputc(MIDI_DIVISIONS&0xFF,MIDIOut);
-        if(fwrite(MTrk,1,8,MIDIOut)!=8)
-        { fclose(MIDIOut);MIDIOut=0;return(MIDI_OFF); }
-
-        /* Write out the tempo */
-        WriteTempo(MIDI_DIVISIONS);
-      }
-
-      /* Turn logging off on failure to open MIDIOut */
-      if(!MIDIOut) Switch=MIDI_OFF;
-
-      /* Assign new switch value */
-      Logging=Switch;
-
-      /* If switching logging on... */
-      if(Switch)
-      {
-        /* Start logging without a pause */
-        TickCount=0;
-
-        /* Write instrument changes */
-        for(J=0;J<MIDI_CHANNELS;J++)
-          if((CH[J].Type>=0)&&(CH[J].Type&0x10000))
-          {
-            I=CH[J].Type&~0x10000;
-            CH[J].Type=-1;
-            MIDISetSound(J,I);
-          }
-      }
-    }
-
-  /* Return current logging status */
-  return(Logging);
-}
-
-/** MIDITicks() **********************************************/
-/** Log N 1ms MIDI ticks.                                   **/
-/*************************************************************/
-void MIDITicks(int N)
-{
-  if(Logging&&MIDIOut&&(N>0)) TickCount+=N;
-}
-
-/** MIDISound() **********************************************/
-/** Set sound frequency (Hz) and volume (0..255) for a      **/
-/** given channel.                                          **/
-/*************************************************************/
-void MIDISound(int Channel,int Freq,int Volume)
-{
-  int MIDIVolume,MIDINote,MIDIWheel;
-
-  /* If logging off, file closed, or invalid channel, drop out */
-  if(!Logging||!MIDIOut||(Channel>=MIDI_CHANNELS-1)||(Channel<0)) return;
-  /* Frequency must be in range */
-  if((Freq<MIDI_MINFREQ)||(Freq>MIDI_MAXFREQ)) Freq=0;
-  /* Volume must be in range */
-  if(Volume<0) Volume=0; else if(Volume>255) Volume=255;
-  /* Instrument number must be valid */
-  if(CH[Channel].Type<0) Freq=0;
-
-  if(!Volume||!Freq) NoteOff(Channel);
-  else
-  {
-    /* SND_TRIANGLE is twice quieter than SND_MELODIC */
-    if(CH[Channel].Type==SND_TRIANGLE) Volume=(Volume+1)/2;
-    /* Compute MIDI note parameters */
-    MIDIVolume = (127*Volume+128)/255;
-    MIDINote   = Freqs[Freq/3].Note;
-    MIDIWheel  = Freqs[Freq/3].Wheel;
-
-    /* Play new note */
-    NoteOn(Channel,MIDINote,MIDIVolume);
-
-    /* Change pitch */
-    if(CH[Channel].Pitch!=MIDIWheel)
-    {
-      MIDIMessage(0xE0+SHIFT(Channel),MIDIWheel&0x7F,(MIDIWheel>>7)&0x7F);
-      CH[Channel].Pitch=MIDIWheel;
-    }
-  }
-}
-
-/** MIDISetSound() *******************************************/
-/** Set sound type for a given channel.                     **/
-/*************************************************************/
-void MIDISetSound(int Channel,int Type)
-{
-  /* Channel must be valid */
-  if((Channel>=MIDI_CHANNELS-1)||(Channel<0)) return;
-
-  /* If instrument changed... */
-  if(CH[Channel].Type!=Type)
-  {
-    /* If logging off or file closed, drop out */
-    if(!Logging||!MIDIOut) CH[Channel].Type=Type|0x10000;
-    else
-    {
-      CH[Channel].Type=Type;
-      if(Type<0) NoteOff(Channel);
-      else
-      {
-        Type=Type&SND_MIDI? (Type&0x7F):Programs[Type%5];
-        MIDIMessage(0xC0+SHIFT(Channel),Type,255);
-      }
-    }
-  }
-}
-
-/** MIDIDrum() ***********************************************/
-/** Hit a drum of a given type with given force.            **/
-/*************************************************************/
-void MIDIDrum(int Type,int Force)
-{
-  /* If logging off or invalid channel, drop out */
-  if(!Logging||!MIDIOut) return;
-  /* The only non-MIDI drum is a click ("Low Wood Block") */
-  Type=Type&DRM_MIDI? (Type&0x7F):77;
-  /* Release previous drum */
-  if(DrumOn) MIDIMessage(0x89,DrumOn,127);
-  /* Hit next drum */
-  if(Type) MIDIMessage(0x99,Type,(Force&0xFF)/2);
-  DrumOn=Type;
-}
-
-/** MIDIMessage() ********************************************/
-/** Write out a MIDI message.                               **/
-/*************************************************************/
-void MIDIMessage(byte D0,byte D1,byte D2)
-{
-  /* Write number of ticks that passed */
-  WriteDelta();
-
-  /* Write out the command */
-  if(D0!=LastMsg) { LastMsg=D0;fputc(D0,MIDIOut); }
-
-  /* Write out the arguments */
-  if(D1<128)
-  {
-    fputc(D1,MIDIOut);
-    if(D2<128) fputc(D2,MIDIOut);
-  }
-}
-
-/** NoteOn() *************************************************/
-/** Turn on a note on a given channel.                      **/
-/*************************************************************/
-void NoteOn(byte Channel,byte Note,byte Level)
-{
-  Note  = Note>0x7F? 0x7F:Note;
-  Level = Level>0x7F? 0x7F:Level;
-
-  if((CH[Channel].Note!=Note)||(CH[Channel].Level!=Level))
-  {
-    if(CH[Channel].Note>=0) NoteOff(Channel);
-    MIDIMessage(0x90+SHIFT(Channel),Note,Level);
-    CH[Channel].Note=Note;
-    CH[Channel].Level=Level;
-  }
-}
-
-/** NoteOff() ************************************************/
-/** Turn off a note on a given channel.                     **/
-/*************************************************************/
-void NoteOff(byte Channel)
-{
-  if(CH[Channel].Note>=0)
-  {
-    MIDIMessage(0x80+SHIFT(Channel),CH[Channel].Note,127);
-    CH[Channel].Note=-1;
-  }
-}
-
-/** WriteDelta() *********************************************/
-/** Write number of ticks since the last MIDI command and   **/
-/** reset the counter.                                      **/
-/*************************************************************/
-void WriteDelta(void)
-{
-  if(TickCount<128) fputc(TickCount,MIDIOut);
-  else
-  {
-    if(TickCount<128*128)
-    {
-      fputc((TickCount>>7)|0x80,MIDIOut);
-      fputc(TickCount&0x7F,MIDIOut);
-    }
-    else
-    {
-      fputc(((TickCount>>14)&0x7F)|0x80,MIDIOut);
-      fputc(((TickCount>>7)&0x7F)|0x80,MIDIOut);
-      fputc(TickCount&0x7F,MIDIOut);
-    }
-  }
-
-  TickCount=0;
-}
-
-/** WriteTempo() *********************************************/
-/** Write out soundtrack tempo (Hz).                        **/
-/*************************************************************/
-void WriteTempo(int Freq)
-{
-  int J;
-
-  J=500000*MIDI_DIVISIONS*2/Freq;
-  WriteDelta();
-  fputc(0xFF,MIDIOut);
-  fputc(0x51,MIDIOut);
-  fputc(0x03,MIDIOut);
-  fputc((J>>16)&0xFF,MIDIOut);
-  fputc((J>>8)&0xFF,MIDIOut);
-  fputc(J&0xFF,MIDIOut);
-}

+ 10 - 0
src/apu/apu.c

@@ -0,0 +1,10 @@
+/*
+ *  APU emulation - The peTI-NESulator Project
+ *  apu.c
+ *
+ *  Created by Manoel TRAPIER.
+ *  Copyright (c) 2003-2018 986-Studio. All rights reserved.
+ *
+ */
+
+/* Empty, for now */

+ 14 - 0
src/include/apu/apu.h

@@ -0,0 +1,14 @@
+/*
+ *  APU emulation - The peTI-NESulator Project
+ *  apu.h
+ *
+ *  Created by Manoel TRAPIER.
+ *  Copyright (c) 2003-2018 986-Studio. All rights reserved.
+ *
+ */
+#ifndef PETI_NESULATOR_APU_H
+#define PETI_NESULATOR_APU_H
+
+/* Empty, for now */
+
+#endif /* PETI_NESULATOR_APU_H */

+ 15 - 102
src/main.c

@@ -50,10 +50,8 @@
 #include <memory/manager.h>
 
 #include <plugins/manager.h>
+#include <apu/apu.h>
 
-#ifdef USE_SOUND
-#include <Sound.h>
-#endif
 
 #if ISPAL && !ISNTSC
 int VBLANK_TIME     = 70;
@@ -362,7 +360,6 @@ byte Page40[256];
 
 void WrHook4000Multiplexer(byte addr, byte value)
 {
-#ifdef USE_SOUND
    static byte SQ1V = 0;
    static byte SQ2V = 0;
    static byte NOIV = 0;
@@ -383,11 +380,10 @@ void WrHook4000Multiplexer(byte addr, byte value)
    static byte Sq2_reg3 = 0;
    
    double SQ = 0.0;
-#endif
+
 
    switch(addr)
    {
-#ifdef USE_SOUND    
 	 case 0x00: /* DDLE NNNN */
 	    Sq1_reg0 = value;
 	    if (Sq1_reg0 & 0x10)
@@ -406,49 +402,17 @@ void WrHook4000Multiplexer(byte addr, byte value)
 	    break;
          
 	    case 0x02:
-	    /*console_printf(Console_Default, "Sq1 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", 
-		Sq1_reg0,
-		(Sq1_reg0&0xC0)>>6,
-		(Sq1_reg0&0x20)>>5,
-		(Sq1_reg0&0x10)>>4,
-		Sq1_reg0&0x0F);
-		console_printf(Console_Default, "Sq1 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", 
-		Sq1_reg1,
-		(Sq1_reg1&0x80)>>8,
-		(Sq1_reg1&0x70)>>4,
-		(Sq1_reg1&0x08)>>3,
-		Sq1_reg1&0x07);
-		console_printf(Console_Default, "Sq1 reg2: 0x%02X\n", value);               
-		console_printf(Console_Default, "Sq1 reg3: 0x%02X\n", Sq1_reg3);*/
 	    SQ1P = value | ((Sq1_reg3&0x7) << 8);
-	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ 
-		(Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/);
-	    //SetSound(0,SND_MELODIC);
-	    
-	    //console_printf(Console_Default, "SQ1V = %d - SQ = %f - SQ1P = %d\n", SQ1V, SQ, SQ1P);
-	    
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); }
-#endif
-	    Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V);
-	    
-         //console_printf(Console_Default, "40%02X: 0x%02X (SQ1P:%d SQ:%f (%d))\n", addr, value, SQ1P, SQ, (int) SQ);
+	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1);
 	    Sq1_reg2 = value;
 	    break;
 	    
 	    case 0x03:
 	    Sq1_reg3 = value;
 	    SQ1P = Sq1_reg2 | ((value&0x7) << 8);
-	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ 
-		(Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/);            
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); }
-#endif
-	    Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V);      
+	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1);
 	    break;
-	    
-	    
-	    
+
 	    case 0x04: 
 	    Sq2_reg0 = value;
 	    if (Sq2_reg0 & 0x10)
@@ -467,31 +431,8 @@ void WrHook4000Multiplexer(byte addr, byte value)
 	    
 	    case 0x06:
 	    Sq2_reg2 = value;
-	    
 	    SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8);
-	    
-	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ 
-		(Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/);
-	    
-	    /*       console_printf(Console_Default, "Sq2 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", 
-		Sq2_reg0,
-		(Sq2_reg0&0xC0)>>6,
-		(Sq2_reg0&0x20)>>5,
-		(Sq2_reg0&0x10)>>4,
-		Sq2_reg0&0x0F);
-		console_printf(Console_Default, "Sq2 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", 
-		Sq2_reg1,
-		(Sq2_reg1&0x80)>>8,
-		(Sq2_reg1&0x70)>>4,
-		(Sq2_reg1&0x08)>>3,
-		Sq2_reg1&0x07);
-		console_printf(Console_Default, "Sq2 reg2: 0x%02X\n", value);               
-		console_printf(Console_Default, "Sq2 reg3: 0x%02X\n", Sq2_reg3);
-		console_printf(Console_Default, "SQ2V = %d - SQ = %f - SQ2P = %d\n", SQ2V, SQ, SQ2P);*/
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); }
-#endif
-	    Sound(1, (int) SQ/22, (0xFF/0x0F) * SQ2V);
+	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1);
 	    break;
 	    
 	    case 0x07:
@@ -499,65 +440,36 @@ void WrHook4000Multiplexer(byte addr, byte value)
 	    
 	    SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8);
 	    
-	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ 
-		(Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/);
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); }
-#endif
-	    Sound(1, (int) SQ/22, (0xFF/0x0F) * SQ2V);        
+	    SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1);
+
 	    break;
 	    
 	    case 0x0A:
 	    TRIP = (TRIP & 0xFF00) | value;
 	    SQ = APU_BASEFREQ * 1000 * 1000 / TRIP;
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 127); fclose(fp); }
-#endif
-	    Sound(2, (int) SQ/22, 127);
 	    break;
 	    
 	    case 0x0B:
 	    TRIP = (TRIP & 0x00FF) | ((value&0x7) << 8);;
 	    SQ = APU_BASEFREQ * 1000 * 1000 / TRIP;
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 127); fclose(fp); }
-#endif
-	    Sound(2, (int) SQ/22, 127);
 	    break;
 	    
 	    case 0x0C:
 	    NOIV = value & 0x0F;
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 3, NOIP, NOIV); fclose(fp); }
-#endif
-	    //SetSound(3, SND_NOISE);
-	    Sound(3, (int) SQ/22, (0xFF/0x0F) * NOIV);        
 	    break;
 	    
 	    case 0x0E:
 	    NOIP = value & 0x0F;
 	    SQ = APU_BASEFREQ * 1000 * 1000 / NOIP;
-#ifdef SOUND_LOG
-	 { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 3, NOIP, NOIV); fclose(fp); }
-#endif
-	    //SetSound(3, SND_NOISE);
-	    Sound(3, (int) SQ/22,     NOIV);
 	    break;
+
 	    case 0x0F:
-	    
 	    break;
+
 	    case 0x15:
 	    /* DMC, Noise, Triangle, Sq 2, Sq 1 */
-	    //SetChannels(0, (value&0x01)?0x01:0);
-	    /*        console_printf(Console_Default, "40%02X: 0x%02X [%c%c%c%c%c]\n", addr, value,
-		(value&0x10)?'d':'.',
-		(value&0x08)?'n':'.',
-		(value&0x04)?'t':'.',
-		(value&0x02)?'2':'.',
-		(value&0x01)?'1':'.');*/
-	    
 	    break; 
-#endif   
+
 	    case 0x14:
 	    ppu_fillSprRamDMA(value);
 	    break;
@@ -577,8 +489,7 @@ void WrHook4000Multiplexer(byte addr, byte value)
 
         default:
 	      Page40[addr] = value;
-	    // console_printf(Console_Default, "40%02X: 0x%02X\n", addr, value);       
-	    //        console_printf(Console_Default, "pAPU: 0x%X @ 0x40%X\n", value, addr);
+          break;
    }
    
 }
@@ -598,7 +509,9 @@ byte RdHook4000Multiplexer(byte addr)
 	    
 	 case 0x15:
 	    ret = 0x1F;
-	 default:
+        break;
+
+   default:
 	    ret = 0x42;
    }   
    return ret;