int snd_init_firmware(const char *filename) { file_t f; size_t sz; uint8 *buff; f = fs_open(filename, O_RDONLY); if(f < 0) { ds_printf("DS_ERROR: Can't open firmware %s\n", filename); return -1; } sz = fs_total(f); ds_printf("DS_PROCESS: Loading firmware %s (%d bytes) into SPU RAM\n", filename, sz); buff = (uint8*)malloc(sz); fs_read(f, buff, sz); fs_close(f); spu_disable(); spu_memset(0, 0, AICA_RAM_START); spu_memload(0, buff, sz); /* Enable the AICA and give it a few ms to start up */ spu_enable(); timer_spin_sleep(10); /* Initialize the RAM allocator */ snd_mem_init(AICA_RAM_START); return 0; }
/* Initialize driver; note that this replaces the AICA program so that if you had anything else going on, it's gone now! */ int snd_init() { int amt; /* Finish loading the stream driver */ if (!initted) { spu_disable(); spu_memset(0, 0, AICA_RAM_START); amt = snd_stream_drv_end - snd_stream_drv; if (amt % 4) amt = (amt + 4) & ~3; printf("snd_init(): loading %d bytes into SPU RAM\n", amt); spu_memload(0, snd_stream_drv, amt); /* Enable the AICA and give it a few ms to start up */ spu_enable(); timer_spin_sleep(10); /* Initialize the RAM allocator */ snd_mem_init(AICA_RAM_START); /* Setup semaphores */ sem_qram = sem_create(1); } initted = 1; return 0; }
void copy_s3m(char *song, int len) { spu_disable(); spu_memload(0x10000, song, len); spu_memload(0, s3mplay, sizeof(s3mplay)); /* Switch channels to mono if uncommented */ /* snd_dbg[1] = 1; */ printf("Load OK, starting ARM\n"); spu_enable(); while(*snd_dbg != 3) ; while(*snd_dbg == 3) ; }
static int load_aica_firmware(void) { int err; const struct firmware *fw_entry; spu_reset(); err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); if (unlikely(err)) return err; /* write firmware into memory */ spu_disable(); spu_memload(0, fw_entry->data, fw_entry->size); spu_enable(); release_firmware(fw_entry); return err; }
static void DCAUD_PlayDevice(_THIS) { SDL_AudioSpec *spec = &this->spec; unsigned int offset; if (this->hidden->playing) { /* wait */ while (aica_get_pos(0) / spec->samples == this->hidden->nextbuf) { thd_pass(); } } offset = this->hidden->nextbuf * spec->size; this->hidden->nextbuf ^= 1; /* Write the audio data, checking for EAGAIN on broken audio drivers */ if (spec->channels == 1) { spu_memload(this->hidden->leftpos + offset, this->hidden->mixbuf, this->hidden->mixlen); } else { offset /= 2; if ((this->spec.format & 255) == 8) { spu_memload_stereo8(this->hidden->leftpos + offset, this->hidden->rightpos + offset, this->hidden->mixbuf, this->hidden->mixlen); } else { spu_memload_stereo16(this->hidden->leftpos + offset, this->hidden->rightpos + offset, this->hidden->mixbuf, this->hidden->mixlen); } } if (!this->hidden->playing) { int mode; this->hidden->playing = 1; mode = (spec->format == AUDIO_S8) ? SM_8BIT : SM_16BIT; if (spec->channels == 1) { aica_play(0, mode, this->hidden->leftpos, 0, spec->samples * 2, spec->freq, 255, 128, 1); } else { aica_play(0, mode, this->hidden->leftpos, 0, spec->samples * 2, spec->freq, 255, 0, 1); aica_play(1, mode, this->hidden->rightpos, 0, spec->samples * 2, spec->freq, 255, 255, 1); } } }
static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_card_aica *dreamcastcard; unsigned int vol; dreamcastcard = kcontrol->private_data; if (unlikely(!dreamcastcard->channel)) return -ETXTBSY; vol = ucontrol->value.integer.value[0]; if (vol > 0xff) return -EINVAL; if (unlikely(dreamcastcard->channel->vol == vol)) return 0; dreamcastcard->channel->vol = ucontrol->value.integer.value[0]; dreamcastcard->master_volume = ucontrol->value.integer.value[0]; spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, dreamcastcard->channel, sizeof(struct aica_channel)); return 1; }
static void startup_aica(struct snd_card_aica *dreamcastcard) { spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, dreamcastcard->channel, sizeof(struct aica_channel)); aica_chn_start(); }
static void audio_write(AVCodecContext *audio, void *buf, size_t size) { if(!aud->channels) { return; } int nsamples = size/(aud->channels*aud->bytes); int writepos = 0; int curpos =0; if (!aud->playing) { aud->sampsize = (65535)/nsamples*nsamples; //printf("audio size=%d n=%d sampsize=%d\n",size,nsamples,aud->sampsize); aud->leftbuf = 0x11000;//AICA_RAM_START;// aud->rightbuf = 0x11000/*AICA_RAM_START*/ + aud->sampsize*aud->bytes; aud->writepos = 0; } else { //curpos = aica_get_pos(0); //if (writepos < curpos && curpos < writepos+nsamples) { //printf("audio:wait"); //} /* while(aud->writepos < curpos && curpos < aud->writepos + nsamples) { curpos = aica_get_pos(0); //timer_spin_sleep(50); //thd_sleep(50); //thd_pass(); thd_sleep(10); //timer_spin_sleep(2); } */ writepos = aud->writepos; curpos = aica_get_pos(0); do { curpos = aica_get_pos(0); } while(writepos < curpos && curpos < writepos + nsamples); //audio_end(); } writepos = aud->writepos * aud->bytes; if (aud->channels == 1) { spu_memload(aud->leftbuf + writepos, buf, size); //spu_memload_mono16(aud->leftbuf + writepos, buf, size); } else { spu_memload_stereo16(aud->leftbuf + writepos, aud->rightbuf + writepos, buf, size); } aud->writepos += nsamples; if (aud->writepos >= aud->sampsize) { aud->writepos = 0; } if (!aud->playing) { int mode; int vol = 255; aud->playing = 1; mode = (aud->bits == 16) ? SM_16BIT : SM_8BIT; if (aud->channels == 1) { aica_play(0,mode,aud->leftbuf,0,aud->sampsize,aud->rate,vol,128,1); } else { // printf("%d %d\n",aud->sampsize,aud->rate); aica_play(0,mode,aud->leftbuf ,0,aud->sampsize,aud->rate,vol, 0,1); aica_play(1,mode,aud->rightbuf,0,aud->sampsize,aud->rate,vol,255,1); } } }
dma_chain_t * dma_initiate(void * dest, void * src, uint32 length, int type) { int irq = 0; dma_chain_t * chain = alloc_chain(); if (chain == NULL) return NULL; chain->dest = (uint32) dest; chain->src = (uint8 *) src; chain->count = length; chain->type = type; chain->waiting_thd = 0; if (type == DMA_TYPE_SPU || type == DMA_TYPE_BBA_RX) { if (type == DMA_TYPE_SPU && (0||nospudma)) { vid_border_color(0, 0, 255); spu_memload(chain->dest, chain->src, chain->count); vid_border_color(0, 0, 0); sem_signal(chain->sema); return chain; } else { //draw_lock(); vid_border_color(0, 0, 255); if (!irq_inside_int()) irq = irq_disable(); if (type == DMA_TYPE_BBA_RX) { /* if (spu_chain_head && spu_chain_head->type == DMA_TYPE_SPU) { */ /* if (!irq_inside_int()) */ /* irq_restore(irq); */ /* free_chain(chain); */ /* return NULL; */ /* } */ chain->waiting_thd = thd_current; } chain->next = spu_chain_head; spu_chain_head = chain; if (!spu_transfering) spu_cb(0); if (!irq_inside_int()) irq_restore(irq); return chain; } } else nospudma = 0; if (!irq_inside_int()) irq = irq_disable(); chain->next = chain_head; chain_head = chain; ta_render_done_cb = renderdone_cb; //vid_border_color(0, 0, 255); if (!irq_inside_int()) irq_restore(irq); return chain; }