summaryrefslogtreecommitdiff
path: root/apps/plugins/rockboy
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockboy')
-rw-r--r--apps/plugins/rockboy/pcm.h2
-rw-r--r--apps/plugins/rockboy/rbsound.c111
-rw-r--r--apps/plugins/rockboy/rockboy.c4
-rw-r--r--apps/plugins/rockboy/sound.c12
4 files changed, 102 insertions, 27 deletions
diff --git a/apps/plugins/rockboy/pcm.h b/apps/plugins/rockboy/pcm.h
index 3719933520..742f0e5a95 100644
--- a/apps/plugins/rockboy/pcm.h
+++ b/apps/plugins/rockboy/pcm.h
@@ -9,7 +9,7 @@ struct pcm
9{ 9{
10 int hz, len; 10 int hz, len;
11 int stereo; 11 int stereo;
12 byte *buf; 12 short *buf;
13 int pos; 13 int pos;
14}; 14};
15 15
diff --git a/apps/plugins/rockboy/rbsound.c b/apps/plugins/rockboy/rbsound.c
index 6d1b24fd9a..92f824aa3b 100644
--- a/apps/plugins/rockboy/rbsound.c
+++ b/apps/plugins/rockboy/rbsound.c
@@ -1,47 +1,120 @@
1
2
3
4#include "rockmacros.h" 1#include "rockmacros.h"
5#include "defs.h" 2#include "defs.h"
6#include "pcm.h" 3#include "pcm.h"
7#include "rc.h" 4#include "rc.h"
8 5
6#define RBSOUND
9 7
10struct pcm pcm; 8struct pcm pcm;
11 9
12static byte buf[4096]; 10#define BUF_SIZE (8192)
11#define DMA_PORTION (1024)
12
13static short buf1_unal[(BUF_SIZE / sizeof(short)) + 2]; // to make sure 4 byte aligned
14static short* buf1;
13 15
16static short front_buf[512];
17
18static short* last_back_pos;
19
20static bool newly_started;
21static int turns;
14 22
15rcvar_t pcm_exports[] = 23rcvar_t pcm_exports[] =
16{ 24{
17 RCV_END 25 RCV_END
18}; 26};
19 27
20
21void pcm_init(void) 28void pcm_init(void)
22{ 29{
23 pcm.hz = 44100; 30 buf1 = (signed short*)((((unsigned int)buf1_unal) >> 2) << 2); /* here i just make sure that buffer is aligned to 4 bytes*/
24 pcm.stereo = 1; 31 newly_started = true;
25 pcm.buf = buf; 32 last_back_pos = buf1;
26 pcm.len = sizeof buf; 33 turns = 0;
27 pcm.pos = 0; 34
35 pcm.hz = 11025;
36 pcm.stereo = 1;
37 pcm.buf = front_buf;
38 pcm.len = (sizeof(front_buf)) / sizeof(short); /* length in shorts, not bytes */
39 pcm.pos = 0;
40
41
42 rb->pcm_play_stop();
43 rb->pcm_set_frequency(11025);
44 rb->pcm_set_volume(200);
28} 45}
29 46
30void pcm_close(void) 47void pcm_close(void)
31{ 48{
32 memset(&pcm, 0, sizeof pcm); 49 memset(&pcm, 0, sizeof pcm);
50 newly_started = true;
51 last_back_pos = buf1;
52 rb->pcm_play_stop();
33} 53}
34 54
55void get_more(unsigned char** start, long* size)
56{
57 int length;
58 unsigned int sar = (unsigned int)SAR0;
59 length = ((unsigned int)buf1) + BUF_SIZE - sar;
60
61 if(turns > 0)
62 {
63 newly_started = true;
64 last_back_pos = buf1;
65 turns = 0;
66 return;
67 } /* sound will stop if no one feeds data*/
68
69 if(length <= 0)
70 {
71 *start = (unsigned char*)buf1;
72 *size = DMA_PORTION;
73 turns++;
74 }
75 else
76 {
77 *start = (unsigned char*)sar;
78 if(length > DMA_PORTION)
79 *size = DMA_PORTION;
80 else
81 *size = length;
82 }
83
84}
85
35int pcm_submit(void) 86int pcm_submit(void)
36{ 87{
37#ifdef RBSOUND 88#ifdef RBSOUND
38 rb->pcm_play_data(pcm.buf,pcm.pos,NULL); 89 while( (turns < 0) && ((((unsigned int)last_back_pos) + pcm.pos * sizeof(short)) > ((unsigned int)SAR0)) && !newly_started) rb->yield(); /* wait until data is passed through DAC or until exit*/
39 while(rb->pcm_is_playing()); /* spinlock */ 90 int shorts_left = ((((unsigned int)buf1) + BUF_SIZE) - ((unsigned int)last_back_pos)) / sizeof(short);
40 pcm.pos = 0; 91 if( shorts_left >= pcm.pos )
41 return 1; 92 {
93 memcpy(last_back_pos,pcm.buf,pcm.pos * sizeof(short));
94 last_back_pos = &last_back_pos[pcm.pos];
95 }
96 else
97 {
98 int last_pos = shorts_left;
99 memcpy(last_back_pos,pcm.buf,shorts_left * sizeof(short));
100 last_back_pos = buf1;
101 shorts_left = pcm.pos - shorts_left;
102 memcpy(last_back_pos,&pcm.buf[last_pos],shorts_left * sizeof(short));
103 last_back_pos = &buf1[shorts_left];
104 turns--;
105 }
106
107 if(newly_started)
108 {
109 rb->pcm_play_data((unsigned char*)buf1,pcm.pos * sizeof(short),&get_more);
110 newly_started = false;
111 }
112
113 pcm.pos = 0;
114 return 1;
42#else 115#else
43 pcm.pos = 0; 116 pcm.pos = 0;
44 return 0; 117 return 0;
45#endif 118#endif
46} 119}
47 120
diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c
index a34fd7bf69..c6d006a131 100644
--- a/apps/plugins/rockboy/rockboy.c
+++ b/apps/plugins/rockboy/rockboy.c
@@ -51,6 +51,7 @@ struct plugin_api* rb;
51int shut,cleanshut; 51int shut,cleanshut;
52char *errormsg; 52char *errormsg;
53int gnuboy_main(char *rom); 53int gnuboy_main(char *rom);
54void pcm_close(void);
54 55
55void die(char *message, ...) 56void die(char *message, ...)
56{ 57{
@@ -124,10 +125,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
124 rb->splash(HZ*2, true, errormsg); 125 rb->splash(HZ*2, true, errormsg);
125 return PLUGIN_ERROR; 126 return PLUGIN_ERROR;
126 } 127 }
127 128 pcm_close();
128 rb->splash(HZ*2, true, "Shutting down.. byebye ^^"); 129 rb->splash(HZ*2, true, "Shutting down.. byebye ^^");
129 130
130 cleanup(); 131 cleanup();
131 132
133
132 return PLUGIN_OK; 134 return PLUGIN_OK;
133} 135}
diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c
index edf31d81b7..10fc504063 100644
--- a/apps/plugins/rockboy/sound.c
+++ b/apps/plugins/rockboy/sound.c
@@ -60,9 +60,9 @@ int pcm_submit(void);
60#define S4 (snd.ch[3]) 60#define S4 (snd.ch[3])
61 61
62rcvar_t sound_exports[] = 62rcvar_t sound_exports[] =
63 { 63{
64 RCV_END 64 RCV_END
65 }; 65};
66 66
67 67
68static void s1_freq_d(int d) 68static void s1_freq_d(int d)
@@ -275,10 +275,10 @@ void sound_mix(void)
275 pcm_submit(); 275 pcm_submit();
276 if (pcm.stereo) 276 if (pcm.stereo)
277 { 277 {
278 pcm.buf[pcm.pos++] = l+128; 278 pcm.buf[pcm.pos++] = (signed short)(l * 256);
279 pcm.buf[pcm.pos++] = r+128; 279 pcm.buf[pcm.pos++] = (signed short)(r * 256);
280 } 280 }
281 else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; 281 else pcm.buf[pcm.pos++] = (signed short)((r+l) * 128);
282 } 282 }
283 } 283 }
284 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); 284 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);