согласно тем же докам - мы можем пропихать без опроса DREQ не более 32 байта. после этого DREQ=0, до тех пор пока часть не отиграет. Затем када снова DREQ=1 - кладем опять 32 байта... итд.
Даже если допустить дергание DREQ во время пересылки данных по SPI, ничего левого не будет - так как мы в высокоприоритетном обработчике прерывания с запрещенными вложенностями. Прерывание по высокому уровню.
8 бит моно 22050Гц. 32 байта буфер , итого 22050/32=690 Гц - воспринимаем прерывание DREQ как прерывание таймера 690 Гц.
Код
#define SND_BUFSIZE 512
Loop:
dos_update_input(); //Апдейтим кнопки
audio_update(); //Обновляем буфер когда сэмулировался фрейм
update_video(); //Отрисовка на экран
goto Loop;
extern volatile u32 Ready; //Признак готовности свежих данных
extern volatile u32 Part; //Смещение которое устанавливает половинки буфера
extern volatile u8 SOUND_BUFFER[SND_BUFSIZE<<1]; //Аудиобуфер из 2-х половинок
void audio_update(void) //Обновляем данные
{
Ready=0; //Данные ещё не готовы
for(i=0;i<SND_BUFSIZE;i++) SOUND_BUFFER[Part+i]=f(i); //Строим волну в одной половинке буфера
Ready=1; //Данные готовы
}
/Макрос посылки 32 байт в VS1003
#define Send32 \
{ \
register u32 i0=(u32)SOUND_BUFFER+(Part^SND_BUFSIZE)+(Kusok<<5); \
register u32 i1=i0+32; \
for(;i0<i1;i0++) SPI(*(u8*)i0); \
}
EX_INTERRUPT_HANDLER(FlagA_ISR) //Обрабоччег прерывания по DREQ
{
*pFIO_FLAG_C=0x0080; //Подтверждаем прерывание
Send32 //Посылаем 32 байта
Kusok++; //Инкрементируем на 32 байта в половинке буфера
if(Kusok==(SND_BUFSIZE>>5)) if(Ready) //Если последний кусок и данные новые поступали
{
Ready=0; //Готовность сбрасываем
Kusok=0; //Сначала в половинку
Part^=SND_BUFSIZE; //Меняем половинки
}
else Kusok=(SND_BUFSIZE>>5)-1; //В противном случае данные не поступали но не можем же мы заткнуться просто так - поэтому играем последнее!!!!
}
В общем данные читаются быстрее, чем они подготавливаются!!!
Потому что выборка 22050 буфер 512 байт, это 22050/512=43 Гц - данные обновляются с меньшей частотой.
Отключаю отрисовку экрана - звук нормальный.
Поэтому сделано воспроизведение последнего куска 32 байта пока не прийдут новые данные.
В общем такое работает - темп слегка растянут - что и нужно!
Но при интенсивном построении буфера - данный метод работает не очень - много хрипа
Поясните как можно сделать лучше...