예제 #1
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        /**
         * PWM_SHIFT(): Shift PWM data.
         * @param src: Channel (L or R) with the source data.
         * @param dest Channel (L or R) for the destination.
         */
        //#define PWM_SHIFT(src, dest)										\
        //{													\
        //	/* Make sure the source FIFO isn't empty. */							\
        //	if (PWM_RP_##src != PWM_WP_##src)								\
        //	{												\
        //		/* Get destination channel output from the source channel FIFO. */			\
        //		PWM_Out_##dest = PWM_FIFO_##src[PWM_RP_##src];						\
        //													\
        //		/* Increment the source channel read pointer, resetting to 0 if it overflows. */	\
        //		PWM_RP_##src = (PWM_RP_##src + 1) & (PWM_BUF_SIZE - 1);					\
        //	}												\
        //}


        /*static void PWM_Shift_Data(void)
         * {
         *  switch (PWM_Mode & 0x0F)
         *  {
         *      case 0x01:
         *      case 0x0D:
         *          // Rx_LL: Right -> Ignore, Left -> Left
         *          PWM_SHIFT(L, L);
         *          break;
         *
         *      case 0x02:
         *      case 0x0E:
         *          // Rx_LR: Right -> Ignore, Left -> Right
         *          PWM_SHIFT(L, R);
         *          break;
         *
         *      case 0x04:
         *      case 0x07:
         *          // RL_Lx: Right -> Left, Left -> Ignore
         *          PWM_SHIFT(R, L);
         *          break;
         *
         *      case 0x05:
         *      case 0x09:
         *          // RR_LL: Right -> Right, Left -> Left
         *          PWM_SHIFT(L, L);
         *          PWM_SHIFT(R, R);
         *          break;
         *
         *      case 0x06:
         *      case 0x0A:
         *          // RL_LR: Right -> Left, Left -> Right
         *          PWM_SHIFT(L, R);
         *          PWM_SHIFT(R, L);
         *          break;
         *
         *      case 0x08:
         *      case 0x0B:
         *          // RR_Lx: Right -> Right, Left -> Ignore
         *          PWM_SHIFT(R, R);
         *          break;
         *
         *      case 0x00:
         *      case 0x03:
         *      case 0x0C:
         *      case 0x0F:
         *      default:
         *          // Rx_Lx: Right -> Ignore, Left -> Ignore
         *          break;
         *  }
         * }
         *
         *
         * void PWM_Update_Timer(unsigned int cycle)
         * {
         *  // Don't do anything if PWM is disabled in the Sound menu.
         *
         *  // Don't do anything if PWM isn't active.
         *  if ((PWM_Mode & 0x0F) == 0x00)
         *      return;
         *
         *  if (PWM_Cycle == 0x00 || (PWM_Cycle_Cnt > cycle))
         *      return;
         *
         *  PWM_Shift_Data();
         *
         *  PWM_Cycle_Cnt += PWM_Cycle;
         *
         *  PWM_Int_Cnt--;
         *  if (PWM_Int_Cnt == 0)
         *  {
         *      PWM_Int_Cnt = PWM_Int;
         *
         *      if (PWM_Mode & 0x0080)
         *      {
         *          // RPT => generate DREQ1 as well as INT
         *          SH2_DMA1_Request(&M_SH2, 1);
         *          SH2_DMA1_Request(&S_SH2, 1);
         *      }
         *
         *      if (_32X_MINT & 1)
         *          SH2_Interrupt(&M_SH2, 6);
         *      if (_32X_SINT & 1)
         *          SH2_Interrupt(&S_SH2, 6);
         *  }
         * }*/


        private int PWM_Update_Scale(pwm_chip chip, int PWM_In)
        {
            if (PWM_In == 0)
            {
                return(0);
            }

            // TODO: Chilly Willy's new scaling algorithm breaks drx's Sonic 1 32X (with PWM drums).
            //# ifdef CHILLY_WILLY_SCALE
            //return (((PWM_In & 0xFFF) - chip->PWM_Offset) * chip->PWM_Scale) >> (8 - PWM_Loudness);
            // Knuckles' Chaotix: Tachy Touch uses the values 0xF?? for negative values
            // This small modification fixes the terrible pops.
            PWM_In &= 0xFFF;
            if ((PWM_In & 0x800) != 0)
            {
                PWM_In |= ~0xFFF;
            }
            return(((PWM_In - chip.PWM_Offset) * chip.PWM_Scale) >> (8 - PWM_Loudness));
            //#else
            //    const int PWM_adjust = ((chip->PWM_Cycle >> 1) + 1);
            //    int PWM_Ret = ((chip->PWM_In & 0xFFF) - PWM_adjust);

            //    // Increase PWM volume so it's audible.
            //    PWM_Ret <<= (5 + 2);

            //    // Make sure the PWM isn't oversaturated.
            //    if (PWM_Ret > 32767)
            //        PWM_Ret = 32767;
            //    else if (PWM_Ret < -32768)
            //        PWM_Ret = -32768;

            //    return PWM_Ret;
            //#endif
        }
예제 #2
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        private void PWM_Update(pwm_chip chip, int[][] buf, int length)
        {
            int tmpOutL;
            int tmpOutR;
            int i;

            //if (!PWM_Enable)
            //	return;

            if (chip.PWM_Out_L == 0 && chip.PWM_Out_R == 0)
            {
                for (i = 0; i < length; i++)
                {
                    buf[0][i] = 0;
                    buf[1][i] = 0;
                }
                return;
            }

            // New PWM scaling algorithm provided by Chilly Willy on the Sonic Retro forums.
            tmpOutL = PWM_Update_Scale(chip, (int)chip.PWM_Out_L);
            tmpOutR = PWM_Update_Scale(chip, (int)chip.PWM_Out_R);

            for (i = 0; i < length; i++)
            {
                buf[0][i] = tmpOutL;
                buf[1][i] = tmpOutR;
            }
        }
예제 #3
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        public override void Update(byte ChipID, int[][] outputs, int samples)
        {
            pwm_chip chip = PWM_Chip[ChipID];

            PWM_Update(chip, outputs, samples);

            visVolume[ChipID][0][0] = outputs[0][0];
            visVolume[ChipID][0][1] = outputs[1][0];
        }
예제 #4
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        //#endif

        private void PWM_Set_Cycle(pwm_chip chip, uint cycle)
        {
            cycle--;
            chip.PWM_Cycle     = (cycle & 0xFFF);
            chip.PWM_Cycle_Cnt = chip.PWM_Cycles;

            //#if CHILLY_WILLY_SCALE
            // TODO: Fix Chilly Willy's new scaling algorithm.
            PWM_Recalc_Scale(chip);
            //#endif
        }
예제 #5
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
 private void PWM_Set_Int(pwm_chip chip, uint int_time)
 {
     int_time &= 0x0F;
     if (int_time != 0)
     {
         chip.PWM_Int = chip.PWM_Int_Cnt = int_time;
     }
     else
     {
         chip.PWM_Int = chip.PWM_Int_Cnt = 16;
     }
 }
예제 #6
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        /**
         * PWM_Init(): Initialize the PWM audio emulator.
         */
        private void PWM_Init(pwm_chip chip)
        {
            chip.PWM_Mode  = 0;
            chip.PWM_Out_R = 0;
            chip.PWM_Out_L = 0;

            for (int i = 0; i < 8; i++)
            {
                chip.PWM_FIFO_R[i] = 0x00;
                chip.PWM_FIFO_L[i] = 0x00;
            }
            chip.PWM_RP_R       = 0;
            chip.PWM_WP_R       = 0;
            chip.PWM_RP_L       = 0;
            chip.PWM_WP_L       = 0;
            chip.PWM_Cycle_Tmp  = 0;
            chip.PWM_Int_Tmp    = 0;
            chip.PWM_FIFO_L_Tmp = 0;
            chip.PWM_FIFO_R_Tmp = 0;

            //PWM_Loudness = 0;
            PWM_Set_Cycle(chip, 0);
            PWM_Set_Int(chip, 0);
        }
예제 #7
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        private void pwm_chn_w(byte ChipID, byte Channel, uint data)
        {
            pwm_chip chip = PWM_Chip[ChipID];

            if (chip.clock == 1)
            {   // old-style commands
                switch (Channel)
                {
                case 0x00:
                    chip.PWM_Out_L = data;
                    break;

                case 0x01:
                    chip.PWM_Out_R = data;
                    break;

                case 0x02:
                    PWM_Set_Cycle(chip, data);
                    break;

                case 0x03:
                    chip.PWM_Out_L = data;
                    chip.PWM_Out_R = data;
                    break;
                }
            }
            else
            {
                switch (Channel)
                {
                case 0x00 / 2:      // control register
                    PWM_Set_Int(chip, data >> 8);
                    break;

                case 0x02 / 2:      // cycle register
                    PWM_Set_Cycle(chip, data);
                    break;

                case 0x04 / 2:      // l ch
                    chip.PWM_Out_L = data;
                    break;

                case 0x06 / 2:      // r ch
                    chip.PWM_Out_R = data;
                    if (chip.PWM_Mode == 0)
                    {
                        if (chip.PWM_Out_L == chip.PWM_Out_R)
                        {
                            // fixes these terrible pops when
                            // starting/stopping/pausing the song
                            chip.PWM_Offset = (int)data;
                            chip.PWM_Mode   = 0x01;
                        }
                    }
                    break;

                case 0x08 / 2:      // mono ch
                    chip.PWM_Out_L = data;
                    chip.PWM_Out_R = data;
                    if (chip.PWM_Mode == 0)
                    {
                        chip.PWM_Offset = (int)data;
                        chip.PWM_Mode   = 0x01;
                    }
                    break;
                }
            }

            return;
        }
예제 #8
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
        public override void Reset(byte ChipID)
        {
            pwm_chip chip = PWM_Chip[ChipID];

            PWM_Init(chip);
        }
예제 #9
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
 private void PWM_Clear_Timer(pwm_chip chip)
 {
     chip.PWM_Cycle_Cnt = 0;
 }
예제 #10
0
파일: pwm.cs 프로젝트: kuma4649/MDSound
 //#if CHILLY_WILLY_SCALE
 // TODO: Fix Chilly Willy's new scaling algorithm.
 private void PWM_Recalc_Scale(pwm_chip chip)
 {
     chip.PWM_Offset = ((int)chip.PWM_Cycle / 2) + 1;
     chip.PWM_Scale  = (0x7FFF00 / chip.PWM_Offset);
 }