Skip to content

Commit d7c6376

Browse files
committed
Audio playback fixes
Partially reverted experimental fix to reduce audio "clicks"
1 parent 44597db commit d7c6376

File tree

4 files changed

+56
-38
lines changed

4 files changed

+56
-38
lines changed

SDL2/src/audio/raspberry/SDL_raspberryaudio.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,20 +149,16 @@ static int RASPBERRYAUD_OpenDevice(_THIS, const char *devname, int iscapture) {
149149

150150
/* Setup DMA control blocks */
151151
for (int i = 0; i < 2; i++) {
152-
uint32_t source_ad = (uint32_t) dma_buffer[i];
153-
while((source_ad & 0xF) != 0) { // Align to 16-bytes boundary
154-
source_ad++;
155-
}
156152
dma_cb[i].ti = DMA_DEST_DREQ | DMA_PERMAP_5 | DMA_SRC_INC | DMA_INTEN;
157-
dma_cb[i].source_ad = 0x40000000 + source_ad;
153+
dma_cb[i].source_ad = 0x40000000 | (((uint32_t) dma_buffer[i] + 15) & ~0xf);
158154
dma_cb[i].dest_ad = 0x7E000000 | 0x20C000 | 0x18;
159155
dma_cb[i].txfr_len = this->spec.samples * this->spec.channels * 4;
160156
dma_cb[i].stride = 0;
161157
dma_cb[i].nextconbk = 0;
162158
}
163159

164160
/* PWM DMA Enable */
165-
PWM->dmac = PWM_ENAB | 0x0001;
161+
PWM->dmac = PWM_ENAB | 0x0008;
166162
PWM->ctl = PWM_USEF2 | PWM_PWEN2 | PWM_USEF1 | PWM_PWEN1 | PWM_CLRF1;
167163

168164
device = this;

kernel/audio.c

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,24 @@ static int16_t * audio_buffer;
3636
int audio_open(uint32_t samples) {
3737
volatile uint32_t * ptr;
3838

39+
max_samples = samples * 2;
40+
3941
for (int i = 0; i < 2; i++) {
4042
if (dma_buffer[i] != NULL) {
4143
free(dma_buffer[i]);
4244
}
43-
dma_buffer[i] = (unsigned char *)malloc(samples * 2 * 4 + 15);
45+
dma_buffer[i] = (unsigned char *)malloc(max_samples * 4 + 15);
4446
if (dma_buffer[i] == NULL) {
4547
return -1;
4648
}
47-
memset(dma_buffer[i], 0, samples * 2 * 4 + 15);
49+
memset(dma_buffer[i], 0, max_samples * 4 + 15);
4850
}
4951

50-
audio_buffer = (int16_t *)malloc(samples * 2 * 2);
52+
audio_buffer = (int16_t *)malloc(max_samples * 2);
5153
if (audio_buffer == NULL) {
5254
return -1;
5355
}
54-
memset(audio_buffer, 0, samples * 2 * 2);
55-
56-
max_samples = samples;
56+
memset(audio_buffer, 0, max_samples * 2);
5757

5858
ptr = (uint32_t *) (GPIO_BASE + GPIO_GPFSEL4);
5959
*ptr = GPIO_FSEL0_ALT0 + GPIO_FSEL5_ALT0;
@@ -74,19 +74,15 @@ int audio_open(uint32_t samples) {
7474
PWM->rng1 = PWM->rng2 = 11336;
7575

7676
for (int i = 0; i < 2; i++) {
77-
uint32_t source_ad = (uint32_t) dma_buffer[i];
78-
while((source_ad & 0xF) != 0) {
79-
source_ad++;
80-
}
8177
dma_cb[i].ti = DMA_DEST_DREQ | DMA_PERMAP_5 | DMA_SRC_INC | DMA_INTEN;
82-
dma_cb[i].source_ad = 0x40000000 + source_ad;
83-
dma_cb[i].dest_ad = 0x7E000000 | 0x20C000 | 0x18;
84-
dma_cb[i].txfr_len = samples * 2 * 4;
78+
dma_cb[i].source_ad = 0x40000000 | (((uint32_t) dma_buffer[i] + 15) & ~0xf);
79+
dma_cb[i].dest_ad = 0x7E000000 | PWM_BASE | PWM_FIF1;
80+
dma_cb[i].txfr_len = max_samples * 4;
8581
dma_cb[i].stride = 0;
8682
dma_cb[i].nextconbk = 0;
8783
}
8884

89-
PWM->dmac = PWM_ENAB | 0x0001; // PWM DMA Enable
85+
PWM->dmac = PWM_ENAB | 0x0008; // PWM DMA Enable
9086
PWM->ctl = PWM_USEF2 | PWM_PWEN2 | PWM_USEF1 | PWM_PWEN1 | PWM_CLRF1;
9187

9288
cur_buffer = 0;
@@ -123,6 +119,10 @@ int audio_get_sample_size() {
123119
void audio_play() {
124120
uint32_t data;
125121

122+
for (int i = 0; i < 2; i++) {
123+
memset(dma_buffer[i], 0, max_samples * 4 + 15);
124+
}
125+
126126
IRQ->irq1Enable = INTERRUPT_DMA0;
127127

128128
DMA->enable = DMA_EN0; // Set DMA Channel 0 Enable Bit
@@ -144,7 +144,6 @@ void audio_play() {
144144

145145
void audio_stop() {
146146
IRQ->irq1Disable = INTERRUPT_DMA0;
147-
DMA->ch[0].cs = DMA_RESET;
148147
}
149148

150149
void audio_dma_irq() {
@@ -176,25 +175,18 @@ uint32_t audio_write(int16_t * stream, uint32_t samples) {
176175
*write_ptr++ = data >> SAMPLE_SHIFT;
177176
write_size++;
178177
written++;
179-
}
180-
181-
if (write_size >= max_samples) {
182-
while((DMA->ch[0].cs & DMA_ACTIVE) != 0)
183-
;
184178

185-
DMA->enable = DMA_EN0;
186-
DMA->ch[0].conblk_ad = 0x40000000 | (uint32_t) &dma_cb[cur_buffer];
187-
DMA->ch[0].cs = DMA_ACTIVE;
179+
if (write_size >= max_samples) {
180+
while((DMA->ch[0].cs & DMA_ACTIVE) != 0)
181+
;
188182

189-
cur_buffer = cur_buffer == 0 ? 1 : 0;
190-
write_ptr = (uint32_t *)dma_cb[cur_buffer].source_ad;
191-
write_size = 0;
183+
DMA->enable = DMA_EN0;
184+
DMA->ch[0].conblk_ad = 0x40000000 | (uint32_t) &dma_cb[cur_buffer];
185+
DMA->ch[0].cs = DMA_ACTIVE;
192186

193-
while (write_size < max_samples && written < samples) {
194-
data = *stream++ + 32768;
195-
*write_ptr++ = data >> SAMPLE_SHIFT;
196-
write_size++;
197-
written++;
187+
cur_buffer = cur_buffer == 0 ? 1 : 0;
188+
write_ptr = (uint32_t *)dma_cb[cur_buffer].source_ad;
189+
write_size = 0;
198190
}
199191
}
200192

uspi/include/uspi/synchronize.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,24 @@ void uspi_LeaveCritical (void); // enable interrupts (nested calls possible)
3333
//
3434
// Cache control
3535
//
36+
#define InvalidateInstructionCache() \
37+
__asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0) : "memory")
38+
#define FlushPrefetchBuffer() __asm volatile ("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory")
39+
#define FlushBranchTargetCache() \
40+
__asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0) : "memory")
3641
#define InvalidateDataCache() __asm volatile ("mcr p15, 0, %0, c7, c6, 0" : : "r" (0) : "memory")
3742
#define CleanDataCache() __asm volatile ("mcr p15, 0, %0, c7, c10, 0" : : "r" (0) : "memory")
3843

3944
//
4045
// Barriers
4146
//
42-
#define DataMemBarrier()
47+
#define DataSyncBarrier() __asm volatile ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory")
48+
#define DataMemBarrier() __asm volatile ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory")
49+
50+
#define InstructionSyncBarrier() FlushPrefetchBuffer()
51+
#define InstructionMemBarrier() FlushPrefetchBuffer()
52+
53+
#define CompilerBarrier() __asm volatile ("" ::: "memory")
4354

4455
#ifdef __cplusplus
4556
}

uspi/lib/synchronize.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,29 @@ static volatile boolean s_bWereEnabled;
2929

3030
void uspi_EnterCritical (void)
3131
{
32+
u32 nFlags;
33+
__asm volatile ("mrs %0, cpsr" : "=r" (nFlags));
3234

35+
DisableInterrupts ();
36+
37+
if (s_nCriticalLevel++ == 0)
38+
{
39+
s_bWereEnabled = nFlags & 0x80 ? FALSE : TRUE;
40+
}
41+
42+
DataMemBarrier ();
3343
}
3444

3545
void uspi_LeaveCritical (void)
3646
{
47+
DataMemBarrier ();
3748

49+
assert (s_nCriticalLevel > 0);
50+
if (--s_nCriticalLevel == 0)
51+
{
52+
if (s_bWereEnabled)
53+
{
54+
EnableInterrupts ();
55+
}
56+
}
3857
}

0 commit comments

Comments
 (0)