smb improvements (rodries)
[libogc.git] / wiiuse / speaker.c
blob7cbc87488e7d7922c98501062bd55d2872e92ede
1 #include <stdio.h>
2 #include <math.h>
3 #include <string.h>
4 #include <time.h>
6 #ifndef WIN32
7 #include <unistd.h>
8 #endif
9 #ifdef GEKKO
10 #include <ogcsys.h>
11 #endif
12 #include "definitions.h"
13 #include "wiiuse_internal.h"
14 #include "speaker.h"
16 #define WENCMIN(a,b) ((a)>(b)?(b):(a))
17 #define ABS(x) ((s32)(x)>0?(s32)(x):-((s32)(x)))
19 static const int yamaha_indexscale[] = {
20 230, 230, 230, 230, 307, 409, 512, 614,
21 230, 230, 230, 230, 307, 409, 512, 614
24 static const int yamaha_difflookup[] = {
25 1, 3, 5, 7, 9, 11, 13, 15,
26 -1, -3, -5, -7, -9, -11, -13, -15
29 static ubyte __wiiuse_speaker_vol = 0x40;
30 static ubyte __wiiuse_speaker_defconf[7] = { 0x00,0x00,0xD0,0x07,0x40,0x0C,0x0E };
32 static __inline__ short wenc_clip_short(int a)
34 if((a+32768)&~65535) return (a>>31)^32767;
35 else return a;
38 static __inline__ int wenc_clip(int a,int amin,int amax)
40 if(a<amin) return amin;
41 else if(a>amax) return amax;
42 else return a;
45 ubyte wencdata(WENCStatus *info,short sample)
47 int nibble,delta;
49 if(!info->step) {
50 info->predictor = 0;
51 info->step = 127;
54 delta = sample - info->predictor;
55 nibble = WENCMIN(7,(ABS(delta)*4)/info->step) + ((delta<0)*8);
57 info->predictor += ((info->step*yamaha_difflookup[nibble])/8);
58 info->predictor = wenc_clip_short(info->predictor);
59 info->step = (info->step*yamaha_indexscale[nibble])>>8;
60 info->step = wenc_clip(info->step,127,24567);
62 return nibble;
65 void wiiuse_set_speaker(struct wiimote_t *wm,int status)
67 ubyte conf[7];
68 ubyte buf = 0x00;
70 if(!wm) return;
72 if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) {
73 WIIUSE_DEBUG("Tried to enable speaker, will wait until handshake finishes.\n");
74 if(status)
75 WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_INIT);
76 else
77 WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_INIT);
78 return;
81 if(status) {
82 if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) {
83 wiiuse_status(wm,NULL);
84 return;
86 } else {
87 if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) {
88 wiiuse_status(wm,NULL);
89 return;
94 buf = 0x04;
95 wiiuse_sendcmd(wm,WM_CMD_SPEAKER_MUTE,&buf,1,NULL);
97 if (!status) {
98 WIIUSE_DEBUG("Disabled speaker for wiimote id %i.", wm->unid);
100 buf = 0x01;
101 wiiuse_write_data(wm,WM_REG_SPEAKER_REG1,&buf,1,NULL);
103 buf = 0x00;
104 wiiuse_write_data(wm,WM_REG_SPEAKER_REG3,&buf,1,NULL);
106 buf = 0x00;
107 wiiuse_sendcmd(wm,WM_CMD_SPEAKER_ENABLE,&buf,1,NULL);
109 wiiuse_status(wm,NULL);
110 return;
113 memcpy(conf,__wiiuse_speaker_defconf,7);
115 buf = 0x04;
116 wiiuse_sendcmd(wm,WM_CMD_SPEAKER_ENABLE,&buf,1,NULL);
118 buf = 0x01;
119 wiiuse_write_data(wm,WM_REG_SPEAKER_REG3,&buf,1,NULL);
121 buf = 0x08;
122 wiiuse_write_data(wm,WM_REG_SPEAKER_REG1,&buf,1,NULL);
124 conf[2] = 0xd0;
125 conf[3] = 0x07;
126 conf[4] = __wiiuse_speaker_vol;
127 wiiuse_write_data(wm,WM_REG_SPEAKER_BLOCK,conf,7,NULL);
129 buf = 0x01;
130 wiiuse_write_data(wm,WM_REG_SPEAKER_REG2,&buf,1,NULL);
132 buf = 0x00;
133 wiiuse_sendcmd(wm,WM_CMD_SPEAKER_MUTE,&buf,1,NULL);
135 wiiuse_status(wm,NULL);
136 return;
139 void set_speakervol(struct wiimote_t *wm,ubyte vol)
141 __wiiuse_speaker_vol = vol;