home *** CD-ROM | disk | FTP | other *** search
- /*
- Filemaster - Multitasking directory utility.
- Copyright (C) 2000 Toni Wilen
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <devices/audio.h>
- #include <graphics/gfxbase.h>
- #include <datatypes/datatypes.h>
- #include <datatypes/datatypesclass.h>
- #include <datatypes/soundclass.h>
- #include <proto/all.h>
- #include <proto/datatypes.h>
- #include <stdio.h>
- #include <string.h>
- #include "fmnode.h"
- #include "child.h"
- #include "fmdos.h"
- #include "fmlocale.h"
- #include "fmgui.h"
- #include "audio.h"
-
- void stopoldmod(void);
- struct IOAudio* allocaudio(struct FMList*);
- void modinfotxt(struct FMList*);
- WORD checkoldaudio(struct FMList*);
-
- extern struct FMMain fmmain;
- extern struct FMConfig *fmconfig;
- extern UBYTE auddev[];
-
- APTR __asm startptplay(register __a0 UBYTE**);
- void __asm stopptplay(register __a0 APTR);
-
- WORD modplay(struct FMHandle*,struct CMenuConfig*);
-
- void __saveds playmod(void)
- {
- struct ProcMsg *pm;
- struct FMList *slist;
- struct FMNode *node;
- struct FMHandle *h;
-
- pm=sinitproc();
- priority(pm->cmc);
- slist=fmmain.sourcedir;
- if (!(setalloc(slist,1))) {
- initproc(0,0);
- goto endi;
- }
- initproc(slist,pm->cmc->label);
- priority(pm->cmc);
- if(sselected(slist,1)) {
- if ((node=findselnode(slist))) {
- if (h=openfile(slist,NDFILE(node),OFNORMAL|OFDECRUNCH)) {
- modplay(h,pm->cmc);
- closefile(h);
- }
- node->flags&=~NSELECTED;
- outputlistline(slist,node);
- }
- }
- endproc(slist);
- endi:
- deinitproc(pm);
- }
-
- void stopoldmod(void)
- {
- WORD cnt;
- if (fmmain.modflag==MODPLAY) {
- fmmain.modflag=0;
- if (fmmain.modptr) stopptplay(fmmain.modptr);
- fmmain.modptr=0;
- for(cnt=0;cnt<33;cnt++) {
- freemem(fmmain.starts[cnt]);
- fmmain.starts[cnt]=0;
- }
- if(fmmain.audio) {
- closedevice((struct IORequest*)fmmain.audio);
- fmmain.audio=0;
- }
- }
- }
-
- struct Sample {
- UBYTE name[22];
- UWORD length;
- UBYTE finetune;
- UBYTE volume;
- UWORD repeat;
- UWORD replen;
- };
- struct MK {
- UBYTE name[20];
- struct Sample sample[31];
- UBYTE songlength;
- UBYTE none;
- UBYTE positions[128];
- ULONG mk;
- };
-
- WORD modplay(struct FMHandle *h,struct CMenuConfig *cmc)
- {
- UBYTE tpats[1084];
- UBYTE *tpatptr,*ptr1;
- LONG patts=1084,cnt,samplelen,totsamples,maxpat=0;
- WORD smpcnt=0,checked=0;
- struct MK *mk;
- struct FMList *list;
-
- list=h->owner;
- stopoldmod();
- changename(list,cmc->label);
- priority(cmc);
- sformatmsg(list->fmmessage1,MSG_FILECLICK_MODULE,h->filename);
- fmmessage(list);
- if(checkoldaudio(list)) return(0);
- tpatptr=tpats;
- list->flags|=LUPDATEMSG;
- if (readbufferfile(h,tpatptr,patts)==patts) {
- ptr1=tpatptr+952;
- while(ptr1!=(tpatptr+1080)) {
- if (*ptr1>maxpat) maxpat=*ptr1;
- ptr1++;
- }
- maxpat++;
- maxpat<<=10;
- fmmain.starts[0]=allocvec(list,patts+maxpat,MEMF_PUBLIC);
- fmmain.starts[1]=allocvec(list,4,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
- if(fmmain.starts[0]&&fmmain.starts[1]) {
- ptr1=tpatptr;
- for(cnt=0;cnt<patts;cnt++) *(fmmain.starts[0]+cnt)=*ptr1++;
- sformatmsg(list->fmmessage2,MSG_AUDIO_MODINFOTXT1,(LONG)maxpat>>10);
- if (readbufferfile(h,fmmain.starts[0]+patts,maxpat)==maxpat) {
- mk=(struct MK*)fmmain.starts[0];
- totsamples=0;
- for(cnt=2;cnt<33;cnt++) {
- samplelen=((LONG)(mk->sample[cnt-2].length))<<1;
- sformatmsg(list->fmmessage2,MSG_AUDIO_MODINFOTXT2,(LONG)(cnt-2),samplelen,(WORD)(totsamples*100/(h->size-(maxpat+patts))));
- if(testabort(list)&&askabort(list)) goto merr;
- totsamples+=samplelen;
- if (samplelen) {
- smpcnt++;
- if(!(fmmain.starts[cnt]=allocvec(list,samplelen,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))) goto merr;
- if(h->size-h->position<samplelen) {
- if(checked) {
- samplelen=-1;
- } else {
- samplelen=h->size-h->position;
- checked=1;
- }
- }
- if(readbufferfile(h,fmmain.starts[cnt],samplelen)!=samplelen) goto merr;
- }
- }
- goto modok;
- }
- }
- }
- merr:
- for (cnt=0;cnt<33;cnt++) {
- freemem(fmmain.starts[cnt]);
- fmmain.starts[cnt]=0;
- }
- return(0);
- modok:
- list->flags&=~LUPDATEMSG;
- fmmain.modflag=MODPLAY;
- sformatmsg(list->fmmessage1,MSG_AUDIO_MODINFOTXT3,(LONG)(maxpat>>10),(LONG)*(fmmain.starts[0]+950),(LONG)smpcnt,totsamples);
- list->fmmessage2[0]=0;
- if (!(fmmain.audio=allocaudio(list))) {
- stopoldmod();
- } else if (!(fmmain.modptr=startptplay(fmmain.starts))) {
- strcpy(list->fmmessage1,getstring(MSG_AUDIO_NOCIA));
- stopoldmod();
- }
- fmmessage(list);
- return(1);
- }
-
- void __saveds modinfo(void)
- {
- struct ProcMsg *pm;
- struct FMList *slist;
- register struct FMNode *node;
- struct FMHandle *h;
- WORD ret=1;
-
- pm=sinitproc();
- priority(pm->cmc);
- slist=fmmain.sourcedir;
- if (!(setalloc(slist,1))) {
- initproc(0,0);
- goto endi;
- }
- initproc(slist,pm->cmc->label);
- priority(pm->cmc);
- if(fmmain.modflag==MODPLAY&&findselnode(slist)) {
- ret=requestmsg(pm->cmc->label,MSG_YES,MSG_NO,MSG_AUDIO_LOAD);
- }
- if (ret&&(node=findselnode(slist))) {
- if (h=openfile(slist,NDFILE(node),OFNORMAL|OFDECRUNCH)) {
- modplay(h,pm->cmc);
- }
- node->flags&=~NSELECTED;
- closefile(h);
- }
- if(fmmain.modflag==MODPLAY) {
- modinfotxt(slist);
- } else {
- strcpymsg(slist->fmmessage1,MSG_MAIN_NOSOURCEFILE);
- fmmessage(slist);
- }
- outputlist(slist);
- endproc(slist);
- endi:
- deinitproc(pm);
- }
-
- WORD showtext(struct FMHandle*,WORD);
-
- void modinfotxt(struct FMList *l)
- {
- WORD cnt,cnt2;
- UBYTE *txt,*txt2;
- UBYTE *ptr,*ptr2;
- LONG len,rep,replen;
- WORD fine,vol;
- struct FMHandle *h;
- UBYTE name[21];
- UBYTE sample[23];
-
- ptr2=name;
- for(cnt2=0;cnt2<20;cnt2++) {
- if(*(fmmain.starts[0]+cnt2)>=32) *ptr2++=*(fmmain.starts[0]+cnt2);
- }
- *ptr2=0;
- if(!(txt2=allocvec(l,3000,0))) return;
- ptr=fmmain.starts[0]+20; txt=txt2;
- strcpy(txt,getstring(MSG_AUDIO_MODINFO1));
- txt+=strlen(txt); *txt++='\n';
- for(cnt=0;cnt<31;cnt++) {
- len=((LONG)(*((UWORD*)(ptr+22))))<<1;
- rep=((LONG)(*((UWORD*)(ptr+26))))<<1;
- replen=((LONG)(*((UWORD*)(ptr+28))))<<1;
- fine=ptr[24]&0x0f;
- if(fine>=8) fine-=16;
- vol=ptr[25];
- ptr2=sample;
- for(cnt2=0;cnt2<22;cnt2++) {
- if(ptr[cnt2]>=32) *ptr2++=ptr[cnt2];
- }
- *ptr2=0;
- sformatmsg(txt,MSG_AUDIO_MODINFO2,cnt,sample,len,fine,vol,rep,replen);
- txt+=strlen(txt); *txt++='\n';
- ptr+=30;
- }
- *txt++=0;
- if (h=openfile(l,name,OFFAKE|OFNORMAL)) {
- h->decbuffer=txt2;
- h->size=txt-txt2-1;
- showtext(h,1);
- closefile(h);
- }
- freemem(txt2);
- }
-
- WORD playsample(struct FMHandle*,struct CMenuConfig*);
-
- void __saveds playsamplefile(void)
- {
- struct ProcMsg *pm;
- struct FMList *slist;
- register struct FMNode *node;
- struct FMHandle *h;
-
- pm=sinitproc();
- slist=fmmain.sourcedir;
- if (!(setalloc(slist,1))) {
- initproc(slist,0);
- goto endi;
- }
- initproc(slist,pm->cmc->label);
- priority(pm->cmc);
- if(sselected(slist,1)) {
- if ((node=findselnode(slist))) {
- if (h=openfile(slist,NDFILE(node),OFNORMAL|OFDECRUNCH)) {
- if(!isdatatypes(h,GID_SOUND)) playsample(h,pm->cmc);
- }
- node->flags&=~NSELECTED;
- outputlistline(slist,node);
- closefile(h);
- }
- }
- endproc(slist);
- endi:
- deinitproc(pm);
- }
-
- void __asm initaudio(register __a0 UBYTE*,register __d0 LONG,register __d1 WORD);
- void __asm endaudio(void);
- void __asm waitaudio(register __a0 struct DosLibrary*);
- void __asm startaudio(register __a0 UBYTE*,register __d0 LONG);
-
- struct AudioConfig {
- LONG smemlen;
- UWORD hz;
- unsigned type:2; //0=ask,1=disk,2=mem
- unsigned askhz:2;
- };
-
- WORD playdatatypesample(struct FMHandle *h,struct DataType *dt,struct CMenuConfig *cmc)
- {
- Object *obj;
- LONG type;
- UBYTE *src;
- LONG slen,secs;
- struct VoiceHeader *vhdr;
- struct timerequest *str;
- struct DataTypeHeader *dth;
- WORD ret=0;
-
- changename(h->owner,cmc->label);
- priority(cmc);
- dth=dt->dtn_Header;
- sformatmsg(h->owner->fmmessage1,MSG_FILECLICK_SOUND,dth->dth_Name,h->filename);
- fmmessage(h->owner);
-
- if(h->flags&OFDECRUNCH) {
- type=DTST_RAM;
- src=h->decbuffer;
- } else {
- type=DTST_FILE;
- src=h->filename;
- }
- if(!(obj=NewDTObject(src,DTA_SourceType,type,DTA_GroupID,GID_SOUND,SDTA_Volume,64L,SDTA_Cycles,1L,TAG_DONE))) goto error;
- if(GetDTAttrs(obj,SDTA_SampleLength,&slen,SDTA_VoiceHeader,&vhdr,TAG_DONE)!=2) goto error;
- if(!slen||!vhdr) goto error;
- sformatmsg(h->owner->fmmessage1,MSG_AUDIO_INFO1,dth->dth_Name,h->filename,slen,(LONG)vhdr->vh_SamplesPerSec);
- fmmessage(h->owner);
-
- str=(struct timerequest*)opendevice(h->owner,"timer.device",UNIT_VBLANK,0,sizeof(struct timerequest));
- if(!str) goto error;
- str->tr_node.io_Command=TR_ADDREQUEST;
- secs=slen/vhdr->vh_SamplesPerSec;
- str->tr_time.tv_micro=(1000000/vhdr->vh_SamplesPerSec)*(slen%vhdr->vh_SamplesPerSec);
- SendIO((struct IORequest*)str);
- DoMethod(obj,DTM_TRIGGER,0,STM_PLAY,0);
- WaitIO((struct IORequest*)str);
- closedevice((struct IORequest*)str);
-
- error:
- if(obj) DisposeDTObject(obj);
- return(ret);
- }
-
- WORD playsample(struct FMHandle *h,struct CMenuConfig *cmc)
- {
- struct GUIBase *gb;
- struct AudioConfig *sconfig;
- ULONG longi1,longi2,ifflen,len1,clock;
- struct VoiceHeader vhdr;
- WORD ret=0,fvhdr=0,iff=0;
- WORD period;
- UBYTE *varabuf=0;
- UBYTE *smem1=0,*smem2=0,*chippi=0,*vara;
- LONG readlen,smemlen,playmem,totlen;
- LONG value;
- UBYTE ptype;
-
- extern struct GfxBase *GfxBase;
- extern struct DosLibrary *DOSBase;
-
- changename(h->owner,cmc->label);
- priority(cmc);
- if(!(sconfig=getconfig(cmc))) return(0);
- sconfig->smemlen&=~1;
- sformatmsg(h->owner->fmmessage1,MSG_FILECLICK_SOUND,"8SVX",h->filename);
- fmmessage(h->owner);
- stopoldmod();
- if(checkoldaudio(h->owner)) return(0);
- smemlen=sconfig->smemlen;
- if(readbufferfile(h,&longi1,4)!=4) goto perr;
- if(readbufferfile(h,&ifflen,4)!=4) goto perr;
- if(readbufferfile(h,&longi2,4)!=4) goto perr;
- ifflen-=4;
- if(longi1=='FORM'&&longi2=='8SVX') iff=1;
- vhdr.vh_SamplesPerSec=sconfig->hz;
- if (iff) {
- if(ifflen>h->size-8) goto pcorrupt;
- for(;;) {
- if (readbufferfile(h,&longi1,4)!=4) goto perr;
- if (readbufferfile(h,&len1,4)!=4) goto perr;
- ifflen-=8;
- if (longi1=='BODY') break;
- switch(longi1)
- {
- case 'VHDR':
- if(len1!=sizeof(struct VoiceHeader)) goto pcorrupt;
- if(readbufferfile(h,&vhdr,len1)!=len1) goto perr;
- ifflen-=len1;
- fvhdr=1;
- break;
- default:
- if (len1&1) len1++;
- if (seek(h,len1,OFFSET_CURRENT)<0) goto perr;
- ifflen-=len1;
- break;
- }
- }
- if(!fvhdr) goto pcorrupt;
- } else {
- ifflen=h->size;
- if(seek(h,0,OFFSET_BEGINNING)<0) goto perr;
- }
- if(!iff||sconfig->askhz) {
- gb=getguibase(cmc->label);
- setconnectgroup(gb,1,0,0);
- reqinfomsg(gb,MSG_AUDIO_ASKFREQUENCY,100,guiUC|guiLEFT);
- reqinteger(gb,100,&value,4000,64000);
- buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
- if(!quickreq(gb)) goto perr;
- vhdr.vh_SamplesPerSec=value;
- }
-
- #ifdef V39
- if(GfxBase->DisplayFlags&REALLY_PAL) clock=3546895; else clock=3579545;
- #else
- if(GfxBase->DisplayFlags&PAL) clock=3546895; else clock=3579545;
- #endif
- sformatmsg(h->owner->fmmessage1,MSG_AUDIO_INFO1,"8SVX",h->filename,h->size,(LONG)vhdr.vh_SamplesPerSec);
- fmmessage(h->owner);
- period=clock/vhdr.vh_SamplesPerSec;
- ptype=sconfig->type;
- if(!ptype) {
- ptype=1;
- if(!requestmsg(getstring(MSG_MAIN_REQUEST),MSG_AUDIO_TYPEANSWER1,MSG_AUDIO_TYPEANSWER2,MSG_AUDIO_ASKTYPE)) ptype=2;
- }
- if(ptype==2)
- smem1=allocvec(h->owner,h->size,MEMF_CHIP);
- else
- smem1=allocvec(h->owner,smemlen,MEMF_CHIP);
- if(!smem1) goto perr;
- if(ptype==1) {
- smem2=allocvec(h->owner,smemlen,MEMF_CHIP);
- if(!smem2) goto perr;
- }
- if(!(fmmain.audio=allocaudio(h->owner))) goto perr;
- initaudio(chippi,4,period);
- playmem=0; totlen=ifflen;
- h->owner->flags|=LUPDATEMSG;
- if(ptype==1) {
- while(ifflen>0) {
- waitaudio(DOSBase);
- vara=smem1;smem1=smem2;smem2=vara;
- if(smemlen>ifflen) readlen=ifflen; else readlen=smemlen;
- if(readbufferfile(h,smem1,readlen)!=readlen) goto perr;
- ifflen-=readlen;
- playmem+=readlen;
- sformatmsg(h->owner->fmmessage2,MSG_AUDIO_INFO2,playmem,totlen,(WORD)(playmem*100/totlen));
- if(testabort(h->owner)) {
- endaudio();
- if(askabort(h->owner)) {
- ret=1;
- break;
- }
- initaudio(chippi,4,period);
- }
- startaudio(smem1,readlen);
- WaitTOF();
- WaitTOF();
- }
- } else {
- if(readbufferfile(h,smem1,ifflen)!=ifflen) goto perr;
- while(ifflen>0) {
- if(smemlen>ifflen) readlen=ifflen; else readlen=smemlen;
- sformatmsg(h->owner->fmmessage2,MSG_AUDIO_INFO2,playmem,totlen,(WORD)(playmem*100/totlen));
- fmmessage(h->owner);
- waitaudio(DOSBase);
- ifflen-=readlen;
- if(testabort(h->owner)) {
- endaudio();
- if(askabort(h->owner)) {
- ret=1;
- break;
- }
- initaudio(chippi,4,period);
- }
- startaudio(smem1+playmem,readlen);
- WaitTOF();
- WaitTOF();
- playmem+=readlen;
- }
- }
- h->owner->flags&=~LUPDATEMSG;
- if(ret) {
- initaudio(chippi,4,period);
- } else {
- sformatmsg(h->owner->fmmessage2,MSG_AUDIO_INFO2,playmem,totlen,(WORD)(playmem*100/totlen));
- fmmessage(h->owner);
- }
- waitaudio(DOSBase);
- startaudio(chippi,4);
- waitaudio(DOSBase);
- endaudio();
- ret=1;
- goto perr;
-
- pcorrupt:
- requestmsg(h->owner->workname,0,MSG_OK,MSG_AUDIO_CORRUPT8SVX,h->filename);
- perr:
- endaudio();
- freemem(smem1);
- freemem(smem2);
- freemem(chippi);
- freemem(varabuf);
- if(fmmain.audio) {
- closedevice((struct IORequest*)fmmain.audio);
- fmmain.audio=0;
- }
- return(ret);
- }
-
-
-
- struct IOAudio* allocaudio(struct FMList *list)
- {
- struct MsgPort *mp;
- struct IOAudio *io;
- UBYTE whichchan;
-
- whichchan=15;
- if(mp=CreateMsgPort()) {
- if(io=(struct IOAudio*)CreateIORequest(mp,sizeof(struct IOAudio))) {
- io->ioa_Request.io_Message.mn_Node.ln_Pri=127;
- io->ioa_Request.io_Command=ADCMD_ALLOCATE;
- io->ioa_Request.io_Flags=ADIOF_NOWAIT;
- io->ioa_AllocKey=0;
- io->ioa_Data=&whichchan;
- io->ioa_Length=1;
- if(!OpenDevice(auddev,0,(struct IORequest*)io,0)) return(io);
- DeleteIORequest((struct IOAudio*)io);
- }
- DeleteMsgPort(mp);
- }
- requestmsg(list->workname,0,MSG_OK,MSG_FMDOS_OPENERR,auddev);
- return(0);
- }
-
- WORD checkoldaudio(struct FMList *l)
- {
- if(fmmain.audio) {
- requestmsg(l->workname,0,MSG_OK,MSG_AUDIO_NOAUDIO);
- return(1);
- }
- return(0);
- }
-
- void *hearconfigdefault(struct CMenuConfig *cmc)
- {
- struct AudioConfig *config;
- WORD ret;
-
- ret=allocconfig(cmc,sizeof(struct AudioConfig));
- if(ret<0) return(cmc->moreconfig);
- if(!ret) return(0);
- config=(struct AudioConfig*)cmc->moreconfig;
- config->hz=18000;
- config->smemlen=40000;
- return(cmc->moreconfig);
- }
-
- WORD hearconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
- {
- WORD c;
- struct AudioConfig *ac;
- WORD askhz,playmethod;
- LONG freq,buf;
-
- ac=getconfig(cmc);
- askhz=ac->askhz;
- setguigroup(gb,1,0);
- reqinfomsg(gb,MSG_AUDIO_CONFIG_ASKHZ,200,guiUC|guiLEFT);
- reqinfomsg(gb,MSG_AUDIO_CONFIG_PLAYMETHOD,201,guiUC|guiLEFT);
- reqinfomsg(gb,MSG_AUDIO_CONFIG_FREQUENCY,202,guiUC|guiLEFT);
- reqinfomsg(gb,MSG_AUDIO_CONFIG_BUFFER,203,guiUC|guiLEFT);
- setguigroup(gb,2,0);
- reqcycle2msg(gb,200,&askhz);
- playmethod=ac->type;
- reqcyclemsg(gb,201,&playmethod,MSG_AUDIO_CONFIG_PLAYMETHOD1,MSG_AUDIO_CONFIG_PLAYMETHOD2,MSG_AUDIO_CONFIG_PLAYMETHOD3,0);
- freq=ac->hz;
- reqinteger(gb,202,&freq,4000,64000);
- buf=ac->smemlen;
- reqinteger(gb,203,&buf,4000,99999999);
- commandanswer(gb);
- c=quickreq(gb);
- if(c) {
- ac->type=playmethod;
- ac->askhz=askhz;
- ac->smemlen=buf;
- ac->hz=freq;
- }
- return(c);
- }
-