A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 152 lines 4.4 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Pacbox - a Pacman Emulator for Rockbox 11 * 12 * Based on PIE - Pacman Instructional Emulator 13 * 14 * Namco custom waveform sound generator 3 (Pacman hardware) 15 * 16 * Copyright (c) 2003,2004 Alessandro Scotti 17 * http://www.ascotti.org/ 18 * 19 * This program is free software; you can redistribute it and/or 20 * modify it under the terms of the GNU General Public License 21 * as published by the Free Software Foundation; either version 2 22 * of the License, or (at your option) any later version. 23 * 24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 25 * KIND, either express or implied. 26 * 27 ****************************************************************************/ 28#include "plugin.h" 29#include "wsg3.h" 30 31struct wsg3 wsg3; 32 33static bool wsg3_get_voice(struct wsg3_voice *voice, int index) 34{ 35 int base = 5*index; 36 const unsigned char *regs = wsg3.sound_regs; 37 unsigned x; 38 39 x = regs[0x15 + base] & 0x0F; 40 41 if (x == 0) 42 return false; 43 44 voice->volume = x; 45 46 x = (regs[0x14 + base] & 0x0F); 47 x = (x << 4) | (regs[0x13 + base] & 0x0F); 48 x = (x << 4) | (regs[0x12 + base] & 0x0F); 49 x = (x << 4) | (regs[0x11 + base] & 0x0F); 50 x = (x << 4); 51 52 if (index == 0) 53 { 54 /* The first voice has an extra 4-bit of data */ 55 x |= regs[0x10 + base] & 0x0F; 56 } 57 58 if (x == 0) 59 return false; 60 61 voice->frequency = x; 62 63 voice->waveform = regs[0x05 + base] & 0x07; 64 65 return true; 66} 67 68void wsg3_play_sound(int16_t * buf, int len) 69{ 70 struct wsg3_voice voice; 71 72 if (wsg3_get_voice(&voice, 0)) 73 { 74 unsigned offset = wsg3.wave_offset[0]; 75 unsigned step = voice.frequency * wsg3.resample_step; 76 int16_t * wave_data = wsg3.sound_wave_data + 32 * voice.waveform; 77 int volume = voice.volume; 78 int i; 79 80 for (i = 0; i < len; i++) 81 { 82 /* Should be shifted right by 15, but we must also get rid 83 * of the 10 bits used for decimals */ 84 buf[i] = (int)wave_data[(offset >> 25) & 0x1F] * volume; 85 offset += step; 86 } 87 88 wsg3.wave_offset[0] = offset; 89 } 90 91 if (wsg3_get_voice(&voice, 1)) 92 { 93 unsigned offset = wsg3.wave_offset[1]; 94 unsigned step = voice.frequency * wsg3.resample_step; 95 int16_t * wave_data = wsg3.sound_wave_data + 32 * voice.waveform; 96 int volume = voice.volume; 97 int i; 98 99 for (i = 0; i < len; i++) 100 { 101 /* Should be shifted right by 15, but we must also get rid 102 * of the 10 bits used for decimals */ 103 buf[i] += (int)wave_data[(offset >> 25) & 0x1F] * volume; 104 offset += step; 105 } 106 107 wsg3.wave_offset[1] = offset; 108 } 109 110 if (wsg3_get_voice(&voice, 2)) 111 { 112 unsigned offset = wsg3.wave_offset[2]; 113 unsigned step = voice.frequency * wsg3.resample_step; 114 int16_t * wave_data = wsg3.sound_wave_data + 32 * voice.waveform; 115 int volume = voice.volume; 116 int i; 117 118 for (i = 0; i < len; i++) 119 { 120 /* Should be shifted right by 15, but we must also get rid 121 * of the 10 bits used for decimals */ 122 buf[i] += (int)wave_data[(offset >> 25) & 0x1F] * volume; 123 offset += step; 124 } 125 126 wsg3.wave_offset[2] = offset; 127 } 128} 129 130void wsg3_set_sampling_rate(unsigned sampling_rate) 131{ 132 wsg3.sampling_rate = sampling_rate; 133 wsg3.resample_step = (wsg3.master_clock << 10) / sampling_rate; 134} 135 136void wsg3_set_sound_prom( const unsigned char * prom ) 137{ 138 int i; 139 140 memcpy(wsg3.sound_prom, prom, 32*8); 141 142 /* Copy wave data and convert 4-bit unsigned -> 16-bit signed, 143 * prenormalized */ 144 for (i = 0; i < 32*8; i++) 145 wsg3.sound_wave_data[i] = ((int16_t)wsg3.sound_prom[i] - 8) * 85; 146} 147 148void wsg3_init(unsigned master_clock) 149{ 150 memset(&wsg3, 0, sizeof (struct wsg3)); 151 wsg3.master_clock = master_clock; 152}