1 /* wiisound.c: Wii sound routines
2 Copyright (c) 2008-2009 Bjoern Giesler, Philip Kendall
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 */
19
20 #include <config.h>
21
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "fuse.h"
26 #include "sfifo.h"
27
28 #include <gccore.h>
29 #include <ogc/audio.h>
30
31 #ifndef MIN
32 #define MIN(x,y) ((x) < (y) ? (x) : (y))
33 #endif
34
35 int samplerate;
36 int streamstate;
37 sfifo_t sound_fifo;
38
39 #define BUFSIZE 16384
40 u8 dmabuf[BUFSIZE<<1] ATTRIBUTE_ALIGN(32);
41 int dmalen = BUFSIZE;
42
43 static void
sound_dmacallback(void)44 sound_dmacallback( void )
45 {
46 if( sfifo_used( &sound_fifo ) < 128) return;
47
48 dmalen = MIN( BUFSIZE, sfifo_used( &sound_fifo ) );
49 sfifo_read( &sound_fifo, dmabuf, dmalen );
50 DCFlushRange( dmabuf, dmalen );
51 AUDIO_InitDMA( (u32)dmabuf, dmalen );
52 AUDIO_StartDMA();
53 }
54
55 int
sound_lowlevel_init(const char * device,int * freqptr,int * stereoptr)56 sound_lowlevel_init( const char *device, int *freqptr, int *stereoptr )
57 {
58 switch(*freqptr) {
59 case 32000:
60 samplerate = AI_SAMPLERATE_32KHZ;
61 break;
62 case 48000:
63 samplerate = AI_SAMPLERATE_48KHZ;
64 break;
65 default:
66 printf("Sample rate %d not supported on Wii\n", *freqptr);
67 return 1;
68 }
69
70 sfifo_init( &sound_fifo, BUFSIZE );
71 *stereoptr = 1;
72
73 AUDIO_Init( NULL );
74 AUDIO_SetDSPSampleRate( samplerate );
75
76 #ifndef DISPLAY_AUDIO
77 AUDIO_RegisterDMACallback( sound_dmacallback );
78 memset( dmabuf, 0, BUFSIZE );
79 AUDIO_InitDMA( (u32)dmabuf, BUFSIZE );
80 DCFlushRange( dmabuf, dmalen );
81 AUDIO_StartDMA();
82 #endif
83
84 return 0;
85 }
86
87 void
sound_lowlevel_end(void)88 sound_lowlevel_end( void )
89 {
90 sfifo_flush( &sound_fifo );
91 sfifo_close( &sound_fifo );
92 AUDIO_StopDMA();
93 }
94
95 void
sound_lowlevel_frame(libspectrum_signed_word * data,int len)96 sound_lowlevel_frame(libspectrum_signed_word *data, int len)
97 {
98 int i;
99
100 libspectrum_signed_byte *bytes = (libspectrum_signed_byte*)data;
101 len <<= 1;
102
103 while(len) {
104 if( ( i = sfifo_write( &sound_fifo, bytes, len ) ) < 0 )
105 break;
106 else if( !i )
107 usleep(10000);
108 bytes += i;
109 len -= i;
110 }
111 }
112