summaryrefslogtreecommitdiff
path: root/apps/plugins/rockboy/rbsound.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockboy/rbsound.c')
-rw-r--r--apps/plugins/rockboy/rbsound.c111
1 files changed, 92 insertions, 19 deletions
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