📄 play.c
字号:
/* SCCSID @(#)play.c 1.14 8/4/98 */ #include "play.h"#include "wavehead.h"#include "../mvd.h"#include "../driver/util.h" #include "../driver/low.h"#include "../driver/buffer.h"#include "../constvar.h"#include "../vcxi.h"#include "newcomm.h"#include "playsd.h"#include "stdfunc.h"#include "graphic.h"#define PCM_manage() PCM_continue()int WAVbuf_inited = FALSE;static BYTE * PCM_dmabuf;static BYTE * PCM_databuf;#define PCM_SNDBUF#ifdef PCM_SNDBUFstatic BYTE * PCM_sndrd, *PCM_sndwr, *_PCM_sndbufstart, *_PCM_sndbufend;#define PCMSNDSIZE 1024#endifint SrcType;#if 0static int BlkSize; /* for IMA_ADPCM */#endifstatic int WAV_bufsize; /* accepted value 384/(2*n)*/#define WAV 0x10000#define AU 0x40000 #define PCM 0x20000 /* April 22 */#define S_8BIT 0x01#define S_MONO 0x02#define S_11k 0x08 #define S_22k 0x04#define IMAADPCM 0x10#define MSADPCM 0x20/* encoding for .au file */#define ULAW 0x2000#define PCM8_16 0x1000#define ALAW 0x4000 #define S16STEREO 0#define S16MONO 2 #define S8STEREO 1#define S8MONO 3/* * fill in DMA sound buf (dst) with data from src * depend on srctype, we process the data differently. * if srctype include S_8BIT, we are getting 8 bit samples, we will * extend it to 16 bit by putting it as most significant byte. * if srctype include S_MONO, we will duplicate it to two chanel. * for each src chanel's 16 bit data, it's two bytes need to be inverted. * for src of freaquency 22k and 11k ,we will duplicate it to 44k. */void WAV_fillbuf(BYTE * src, BYTE * dst, int srcsize){ static short last; /* Last data from last chunk */ int i, j; unsigned int *psrc, *pdst; short sb, tmp[4]; int vmax; int scale; psrc=(unsigned int*) src; pdst=(unsigned int*) dst; vmax = (vcx_audio_volume&0xff)*240>>4; if (vmax<15) vmax = -1; if (PCM_ampf==0) { /* keep this simple like this */ for (i=0;i<srcsize<<4;i++) *pdst++ = 0; } else { if (wavelen<=0) { PCM_ampf -= 17; } else if ((PCM_xfersize<<2)+1024<wavelen) PCM_ampf += 4; else PCM_ampf -= 17; if (PCM_ampf<0) PCM_ampf=0; else if (PCM_ampf>vmax) PCM_ampf=vmax; scale = (PCM_ampf<0)?0:PCM_ampf; for (i = 0; i < srcsize << 2; i++) { short last2, sb2; short quarter; sb=(short)((char)(src[i] ^ 0x80)); sb = sb * scale; /* 8b->16b */ last2 = last >> 1; /* 1/2 of last data */ sb2 = sb >> 1; /* 1/2 of new data */ quarter = (last>>2) + (sb>>2); /* 1/4 of (last+new) */ tmp[0] = last; /* 1 , 0 */ tmp[1] = quarter + last2; /* 3/4, 1/4 */ tmp[2] = last2 + sb2; /* 1/2, 1/2 */ tmp[3] = quarter + sb2; /* 1/4, 3/4 */ for (j = 0; j < 4; j++) *pdst++ = (tmp[j]<<16) + tmp[j]; last = sb; } }}void WAV_initbuf(){ int i; BYTE *tmp; if (WAVbuf_inited) return; PCM_dmabuf =(BYTE *) GX_malloc(sizeof(BYTE)<<10); PCM_dmabuf = (BYTE *)(DRAMSEG|(int)PCM_dmabuf); PCM_databuf = (BYTE *) GX_malloc(sizeof(BYTE)<<10); PCM_databuf = (BYTE *)(DRAMSEG|(int)PCM_databuf); WAVbuf_inited = TRUE; #ifdef PCM_SNDBUF _PCM_sndbufstart = (BYTE *) GX_malloc(PCMSNDSIZE * sizeof(BYTE)); _PCM_sndbufstart = (BYTE *)(DRAMSEG|(int)_PCM_sndbufstart); _PCM_sndbufend=_PCM_sndbufstart+PCMSNDSIZE; PCM_sndrd=PCM_sndwr=_PCM_sndbufstart;#endif for (i=0; i<256; i++) { *((int*)PCM_databuf+i) = 0; *((int*)PCM_dmabuf+i) = 0;#ifdef PCM_SNDBUF *((int*)_PCM_sndbufstart+i) = 0;#endif }}void PCM_switchbuf(){#if 1 BYTE *tmp; tmp = PCM_dmabuf; PCM_dmabuf = PCM_databuf; PCM_databuf = tmp; #else int i; for (i=0;i<256;i++) *((int*) PCM_dmabuf+i) = *((int*)PCM_databuf+i);#endif}extern volatile int buf0ready, buf1ready;int wavbuf_switch() { if (PCM_srcsize>0) return 1; if(wav_wrptr!=WavBuf1Begin) { PCM_rd_ptr = WavBuf1Begin; PCM_srcsize = wavbuf1size>>2;#if 1 buf0ready = 0; #endif } else { PCM_rd_ptr = WavBuf0Begin; PCM_srcsize = wavbuf0size>>2;#if 1 buf1ready = 0;#endif }#if 1 if ((!buf0ready) && (!buf1ready)){au_end(0);}#endif return 0;}PCM_fillbuf() { int i, bsize; wavbuf_switch(); if (PCM_srcsize>0 && wavelen>0 && (PCM_xfersize<<2)+64>=wavelen) { if (au_repeat) { PCM_rd_ptr += WAV_headlen; PCM_rd_ptr = (PCM_rd_ptr>>2)<<2; PCM_xfersize=0; PCM_ampf=4; } } if (PCM_srcsize > WAV_bufsize) bsize = WAV_bufsize; else bsize = PCM_srcsize;#ifdef PCM_SNDBUF if (PCM_srcsize>0 && wavelen>0) { for (i=0;i<bsize;i++) *((int*)PCM_sndwr+i)=*((int*)PCM_rd_ptr+i); PCM_sndwr += WAV_bufsize<<2; if (PCM_sndwr>=_PCM_sndbufend) {PCM_sndwr=_PCM_sndbufstart; } if (PCM_srcsize>WAV_bufsize) PCM_rd_ptr+= bsize<<2; PCM_srcsize -= WAV_bufsize; PCM_xfersize += WAV_bufsize; } WAV_fillbuf((char*) PCM_sndrd, PCM_databuf, WAV_bufsize); PCM_sndrd += WAV_bufsize<<2; if (PCM_sndrd>=_PCM_sndbufend) PCM_sndrd=_PCM_sndbufstart;#else if (PCM_srcsize>0 && wavelen>0) { WAV_fillbuf((char*) PCM_rd_ptr, PCM_databuf, WAV_bufsize); if (PCM_srcsize>WAV_bufsize) PCM_rd_ptr+= bsize<<2; PCM_srcsize -= WAV_bufsize; PCM_xfersize += WAV_bufsize; } else { int *p=(int*) PCM_databuf; for (i=0;i<256;i++) p[i]>>=1; PCM_ampf >>= 1; }#endif}int not_enabled = 1;void PCM_startplay(int srcsize){ PCM_srcsize = (srcsize&x00ffffff)>>2; PCM_ampf = 8; PCM_xfersize = 0;#ifdef PCM_SNDBUF PCM_sndrd=PCM_sndwr=_PCM_sndbufstart;#endif PCM_fillbuf(); PCM_continue();}int PCM_continue(){ /* start DMA */ WAV_data_ready = FALSE; PCM_switchbuf(); buscon_xfer(d2a,0,((((int)PCM_dmabuf)&x00ffffff)>>2),256,1); if (not_enabled) { buscon_irq_enable(d2a); not_enabled = 0; } PCM_fillbuf(); WAV_data_ready = TRUE; }static ADPCM_params_t _ADPCM_params_[2];int PlayWAVE(unsigned char *pDataWAVE, int SizeWAVE){ int i; int start; int head; ADPCM_params_t *ADPCM_params; ADPCM_params = _ADPCM_params_; SrcType = 0; wave_header((BYTE *)pDataWAVE, &SrcType, &WAV_bufsize, &start, ADPCM_params);#if 0 BlkSize = (int)ADPCM_params->n_block_alignment;#endif WAV_initbuf(); PCM_rd_ptr += WAV_headlen; PCM_rd_ptr = (PCM_rd_ptr>>2)<<2; wavelen -= (WAV_headlen + start -(int)pDataWAVE); if (wavelen<WAVBUFSIZE-WAV_headlen) PCM_startplay(wavelen); else PCM_startplay(WAVBUFSIZE-WAV_headlen); PCM_rd_ptr = (PCM_rd_ptr>>2)<<2; return 0;}void d2a_interrupt_service() { if (WAV_data_ready) { PCM_manage(); } else{ buscon_xfer(d2a, 0, PCM_zero_start, PCM_zero_size, 1); if (not_enabled) { buscon_irq_enable(d2a); not_enabled = 0; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -