home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  15.0 KB  |  622 lines

  1. /*
  2.      Filemaster - Multitasking directory utility.
  3.      Copyright (C) 2000  Toni Wilen
  4.      
  5.      This program is free software; you can redistribute it and/or
  6.      modify it under the terms of the GNU General Public License
  7.      as published by the Free Software Foundation; either version 2
  8.      of the License, or (at your option) any later version.
  9.      
  10.      This program is distributed in the hope that it will be useful,
  11.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.      GNU General Public License for more details.
  14.      
  15.      You should have received a copy of the GNU General Public License
  16.      along with this program; if not, write to the Free Software
  17.      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <dos/dos.h>
  23. #include <devices/audio.h>
  24. #include <graphics/gfxbase.h>
  25. #include <datatypes/datatypes.h>
  26. #include <datatypes/datatypesclass.h>
  27. #include <datatypes/soundclass.h>
  28. #include <proto/all.h>
  29. #include <proto/datatypes.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include "fmnode.h"
  33. #include "child.h"
  34. #include "fmdos.h"
  35. #include "fmlocale.h"
  36. #include "fmgui.h"
  37. #include "audio.h"
  38.  
  39. void stopoldmod(void);
  40. struct IOAudio* allocaudio(struct FMList*);
  41. void modinfotxt(struct FMList*);
  42. WORD checkoldaudio(struct FMList*);
  43.  
  44. extern struct FMMain fmmain;
  45. extern struct FMConfig *fmconfig;
  46. extern UBYTE auddev[];
  47.  
  48. APTR __asm startptplay(register __a0 UBYTE**);
  49. void __asm stopptplay(register __a0 APTR);
  50.  
  51. WORD modplay(struct FMHandle*,struct CMenuConfig*);
  52.  
  53. void __saveds playmod(void)
  54. {
  55. struct ProcMsg *pm;
  56. struct FMList *slist;
  57. struct FMNode *node;
  58. struct FMHandle *h;
  59.  
  60. pm=sinitproc();
  61. priority(pm->cmc);
  62. slist=fmmain.sourcedir;
  63. if (!(setalloc(slist,1))) {
  64.     initproc(0,0);
  65.     goto endi;
  66. }
  67. initproc(slist,pm->cmc->label);
  68. priority(pm->cmc);
  69. if(sselected(slist,1)) {
  70.     if ((node=findselnode(slist))) {
  71.         if (h=openfile(slist,NDFILE(node),OFNORMAL|OFDECRUNCH)) {
  72.             modplay(h,pm->cmc);
  73.             closefile(h);
  74.         }
  75.         node->flags&=~NSELECTED;
  76.         outputlistline(slist,node);
  77.     }
  78. }
  79. endproc(slist);
  80. endi:
  81. deinitproc(pm);
  82. }
  83.  
  84. void stopoldmod(void)
  85. {
  86. WORD cnt;
  87. if (fmmain.modflag==MODPLAY) {
  88.     fmmain.modflag=0;
  89.     if (fmmain.modptr) stopptplay(fmmain.modptr);    
  90.     fmmain.modptr=0;
  91.     for(cnt=0;cnt<33;cnt++) {
  92.         freemem(fmmain.starts[cnt]);
  93.         fmmain.starts[cnt]=0;
  94.     }
  95.     if(fmmain.audio) {
  96.         closedevice((struct IORequest*)fmmain.audio);
  97.         fmmain.audio=0;
  98.     }
  99. }
  100. }
  101.  
  102. struct Sample {
  103.     UBYTE name[22];
  104.     UWORD length;
  105.     UBYTE finetune;
  106.     UBYTE volume;
  107.     UWORD repeat;
  108.     UWORD replen;
  109. };
  110. struct MK {
  111.     UBYTE name[20];
  112.     struct Sample sample[31];
  113.     UBYTE songlength;
  114.     UBYTE none;
  115.     UBYTE positions[128];
  116.     ULONG mk;
  117. };
  118.  
  119. WORD modplay(struct FMHandle *h,struct CMenuConfig *cmc)
  120. {
  121. UBYTE tpats[1084];
  122. UBYTE *tpatptr,*ptr1;
  123. LONG patts=1084,cnt,samplelen,totsamples,maxpat=0;
  124. WORD smpcnt=0,checked=0;
  125. struct MK *mk;
  126. struct FMList *list;
  127.  
  128. list=h->owner;
  129. stopoldmod();
  130. changename(list,cmc->label);
  131. priority(cmc);
  132. sformatmsg(list->fmmessage1,MSG_FILECLICK_MODULE,h->filename);
  133. fmmessage(list);
  134. if(checkoldaudio(list)) return(0);
  135. tpatptr=tpats;
  136. list->flags|=LUPDATEMSG;
  137. if (readbufferfile(h,tpatptr,patts)==patts) {
  138.     ptr1=tpatptr+952;
  139.     while(ptr1!=(tpatptr+1080)) {
  140.         if (*ptr1>maxpat) maxpat=*ptr1;
  141.         ptr1++;
  142.     }
  143.     maxpat++;
  144.     maxpat<<=10;
  145.     fmmain.starts[0]=allocvec(list,patts+maxpat,MEMF_PUBLIC);
  146.     fmmain.starts[1]=allocvec(list,4,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
  147.     if(fmmain.starts[0]&&fmmain.starts[1]) {
  148.         ptr1=tpatptr;
  149.         for(cnt=0;cnt<patts;cnt++) *(fmmain.starts[0]+cnt)=*ptr1++;
  150.         sformatmsg(list->fmmessage2,MSG_AUDIO_MODINFOTXT1,(LONG)maxpat>>10);
  151.         if (readbufferfile(h,fmmain.starts[0]+patts,maxpat)==maxpat) {
  152.             mk=(struct MK*)fmmain.starts[0];
  153.             totsamples=0;
  154.             for(cnt=2;cnt<33;cnt++) {
  155.                 samplelen=((LONG)(mk->sample[cnt-2].length))<<1;
  156.                 sformatmsg(list->fmmessage2,MSG_AUDIO_MODINFOTXT2,(LONG)(cnt-2),samplelen,(WORD)(totsamples*100/(h->size-(maxpat+patts))));
  157.                 if(testabort(list)&&askabort(list)) goto merr;
  158.                 totsamples+=samplelen;
  159.                 if (samplelen) {
  160.                     smpcnt++;
  161.                     if(!(fmmain.starts[cnt]=allocvec(list,samplelen,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))) goto merr;
  162.                     if(h->size-h->position<samplelen) {
  163.                         if(checked) {
  164.                             samplelen=-1;
  165.                         } else {
  166.                             samplelen=h->size-h->position;
  167.                             checked=1;
  168.                         }
  169.                     }
  170.                     if(readbufferfile(h,fmmain.starts[cnt],samplelen)!=samplelen) goto merr;
  171.                 }
  172.             }
  173.             goto modok;
  174.         }
  175.     }
  176. }
  177. merr:
  178. for (cnt=0;cnt<33;cnt++) {
  179.     freemem(fmmain.starts[cnt]);
  180.     fmmain.starts[cnt]=0;
  181. }
  182. return(0);
  183. modok:
  184. list->flags&=~LUPDATEMSG;
  185. fmmain.modflag=MODPLAY;
  186. sformatmsg(list->fmmessage1,MSG_AUDIO_MODINFOTXT3,(LONG)(maxpat>>10),(LONG)*(fmmain.starts[0]+950),(LONG)smpcnt,totsamples);
  187. list->fmmessage2[0]=0;
  188. if (!(fmmain.audio=allocaudio(list))) {
  189.     stopoldmod();
  190. } else if (!(fmmain.modptr=startptplay(fmmain.starts))) {
  191.     strcpy(list->fmmessage1,getstring(MSG_AUDIO_NOCIA));
  192.     stopoldmod();
  193. }
  194. fmmessage(list);
  195. return(1);
  196. }
  197.  
  198. void __saveds modinfo(void)
  199. {
  200. struct ProcMsg *pm;
  201. struct FMList *slist;
  202. register struct FMNode *node;
  203. struct FMHandle *h;
  204. WORD ret=1;
  205.  
  206. pm=sinitproc();
  207. priority(pm->cmc);
  208. slist=fmmain.sourcedir;
  209. if (!(setalloc(slist,1))) {
  210.     initproc(0,0);
  211.     goto endi;
  212. }
  213. initproc(slist,pm->cmc->label);
  214. priority(pm->cmc);
  215. if(fmmain.modflag==MODPLAY&&findselnode(slist)) {
  216.     ret=requestmsg(pm->cmc->label,MSG_YES,MSG_NO,MSG_AUDIO_LOAD);
  217. }
  218. if (ret&&(node=findselnode(slist))) {
  219.     if (h=openfile(slist,NDFILE(node),OFNORMAL|OFDECRUNCH)) {
  220.         modplay(h,pm->cmc);
  221.     }
  222.     node->flags&=~NSELECTED;
  223.     closefile(h);
  224. }
  225. if(fmmain.modflag==MODPLAY) {
  226.     modinfotxt(slist);
  227. } else {
  228.     strcpymsg(slist->fmmessage1,MSG_MAIN_NOSOURCEFILE);
  229.     fmmessage(slist);
  230. }
  231. outputlist(slist);
  232. endproc(slist);
  233. endi:
  234. deinitproc(pm);
  235. }
  236.  
  237. WORD showtext(struct FMHandle*,WORD);
  238.  
  239. void modinfotxt(struct FMList *l)
  240. {
  241. WORD cnt,cnt2;
  242. UBYTE *txt,*txt2;
  243. UBYTE *ptr,*ptr2;
  244. LONG len,rep,replen;
  245. WORD fine,vol;
  246. struct FMHandle *h;
  247. UBYTE name[21];
  248. UBYTE sample[23];
  249.  
  250. ptr2=name;
  251. for(cnt2=0;cnt2<20;cnt2++) {
  252.     if(*(fmmain.starts[0]+cnt2)>=32) *ptr2++=*(fmmain.starts[0]+cnt2);
  253. }
  254. *ptr2=0;
  255. if(!(txt2=allocvec(l,3000,0))) return;
  256. ptr=fmmain.starts[0]+20; txt=txt2;
  257. strcpy(txt,getstring(MSG_AUDIO_MODINFO1));
  258. txt+=strlen(txt); *txt++='\n';
  259. for(cnt=0;cnt<31;cnt++) {
  260.     len=((LONG)(*((UWORD*)(ptr+22))))<<1;
  261.     rep=((LONG)(*((UWORD*)(ptr+26))))<<1;
  262.     replen=((LONG)(*((UWORD*)(ptr+28))))<<1;
  263.     fine=ptr[24]&0x0f;
  264.     if(fine>=8) fine-=16;
  265.     vol=ptr[25];
  266.     ptr2=sample;
  267.     for(cnt2=0;cnt2<22;cnt2++) {
  268.         if(ptr[cnt2]>=32) *ptr2++=ptr[cnt2];
  269.     }
  270.     *ptr2=0;
  271.     sformatmsg(txt,MSG_AUDIO_MODINFO2,cnt,sample,len,fine,vol,rep,replen);
  272.     txt+=strlen(txt); *txt++='\n';
  273.     ptr+=30;
  274. }
  275. *txt++=0;
  276. if (h=openfile(l,name,OFFAKE|OFNORMAL)) {
  277.     h->decbuffer=txt2;
  278.     h->size=txt-txt2-1;
  279.     showtext(h,1);
  280.     closefile(h);
  281. }
  282. freemem(txt2);
  283. }
  284.  
  285. WORD playsample(struct FMHandle*,struct CMenuConfig*);
  286.  
  287. void __saveds playsamplefile(void)
  288. {
  289. struct ProcMsg *pm;
  290. struct FMList *slist;
  291. register struct FMNode *node;
  292. struct FMHandle *h;
  293.  
  294. pm=sinitproc();
  295. slist=fmmain.sourcedir;
  296. if (!(setalloc(slist,1))) {
  297.     initproc(slist,0);
  298.     goto endi;
  299. }
  300. initproc(slist,pm->cmc->label);
  301. priority(pm->cmc);
  302. if(sselected(slist,1)) {
  303.     if ((node=findselnode(slist))) {
  304.         if (h=openfile(slist,NDFILE(node),OFNORMAL|OFDECRUNCH)) {
  305.             if(!isdatatypes(h,GID_SOUND)) playsample(h,pm->cmc);
  306.         }
  307.         node->flags&=~NSELECTED;
  308.         outputlistline(slist,node);
  309.         closefile(h);
  310.     }
  311. }
  312. endproc(slist);
  313. endi:
  314. deinitproc(pm);
  315. }
  316.  
  317. void __asm initaudio(register __a0 UBYTE*,register __d0 LONG,register __d1 WORD);
  318. void __asm endaudio(void);
  319. void __asm waitaudio(register __a0 struct DosLibrary*);
  320. void __asm startaudio(register __a0 UBYTE*,register __d0 LONG);
  321.  
  322. struct AudioConfig {
  323.     LONG    smemlen;
  324.     UWORD    hz;
  325.     unsigned type:2; //0=ask,1=disk,2=mem
  326.     unsigned askhz:2;
  327. };
  328.  
  329. WORD playdatatypesample(struct FMHandle *h,struct DataType *dt,struct CMenuConfig *cmc)
  330. {
  331. Object *obj;
  332. LONG type;
  333. UBYTE *src;
  334. LONG slen,secs;
  335. struct VoiceHeader *vhdr;
  336. struct timerequest *str;
  337. struct DataTypeHeader *dth;
  338. WORD ret=0;
  339.  
  340. changename(h->owner,cmc->label);
  341. priority(cmc);
  342. dth=dt->dtn_Header;
  343. sformatmsg(h->owner->fmmessage1,MSG_FILECLICK_SOUND,dth->dth_Name,h->filename);
  344. fmmessage(h->owner);
  345.  
  346. if(h->flags&OFDECRUNCH) {
  347.     type=DTST_RAM;
  348.     src=h->decbuffer;
  349. } else {
  350.     type=DTST_FILE;
  351.     src=h->filename;
  352. }
  353. if(!(obj=NewDTObject(src,DTA_SourceType,type,DTA_GroupID,GID_SOUND,SDTA_Volume,64L,SDTA_Cycles,1L,TAG_DONE))) goto error;
  354. if(GetDTAttrs(obj,SDTA_SampleLength,&slen,SDTA_VoiceHeader,&vhdr,TAG_DONE)!=2) goto error;
  355. if(!slen||!vhdr) goto error;
  356. sformatmsg(h->owner->fmmessage1,MSG_AUDIO_INFO1,dth->dth_Name,h->filename,slen,(LONG)vhdr->vh_SamplesPerSec);
  357. fmmessage(h->owner);
  358.  
  359. str=(struct timerequest*)opendevice(h->owner,"timer.device",UNIT_VBLANK,0,sizeof(struct timerequest));
  360. if(!str) goto error;
  361. str->tr_node.io_Command=TR_ADDREQUEST;
  362. secs=slen/vhdr->vh_SamplesPerSec;
  363. str->tr_time.tv_micro=(1000000/vhdr->vh_SamplesPerSec)*(slen%vhdr->vh_SamplesPerSec);
  364. SendIO((struct IORequest*)str);
  365. DoMethod(obj,DTM_TRIGGER,0,STM_PLAY,0);
  366. WaitIO((struct IORequest*)str);
  367. closedevice((struct IORequest*)str);
  368.  
  369. error:
  370. if(obj) DisposeDTObject(obj);
  371. return(ret);
  372. }
  373.  
  374. WORD playsample(struct FMHandle *h,struct CMenuConfig *cmc)
  375. {
  376. struct GUIBase *gb;
  377. struct AudioConfig *sconfig;
  378. ULONG longi1,longi2,ifflen,len1,clock;
  379. struct VoiceHeader vhdr;
  380. WORD ret=0,fvhdr=0,iff=0;
  381. WORD period;
  382. UBYTE *varabuf=0;
  383. UBYTE *smem1=0,*smem2=0,*chippi=0,*vara;
  384. LONG readlen,smemlen,playmem,totlen;
  385. LONG value;
  386. UBYTE ptype;
  387.  
  388. extern struct GfxBase *GfxBase;
  389. extern struct DosLibrary *DOSBase;
  390.  
  391. changename(h->owner,cmc->label);
  392. priority(cmc);
  393. if(!(sconfig=getconfig(cmc))) return(0);
  394. sconfig->smemlen&=~1;
  395. sformatmsg(h->owner->fmmessage1,MSG_FILECLICK_SOUND,"8SVX",h->filename);
  396. fmmessage(h->owner);
  397. stopoldmod();
  398. if(checkoldaudio(h->owner)) return(0);
  399. smemlen=sconfig->smemlen;
  400. if(readbufferfile(h,&longi1,4)!=4) goto perr;
  401. if(readbufferfile(h,&ifflen,4)!=4) goto perr;
  402. if(readbufferfile(h,&longi2,4)!=4) goto perr;
  403. ifflen-=4;
  404. if(longi1=='FORM'&&longi2=='8SVX') iff=1;
  405. vhdr.vh_SamplesPerSec=sconfig->hz;
  406. if (iff) {
  407.     if(ifflen>h->size-8) goto pcorrupt;
  408.     for(;;) {
  409.         if (readbufferfile(h,&longi1,4)!=4) goto perr;
  410.         if (readbufferfile(h,&len1,4)!=4) goto perr;
  411.         ifflen-=8;
  412.         if (longi1=='BODY') break;
  413.         switch(longi1)
  414.         {
  415.             case 'VHDR':
  416.             if(len1!=sizeof(struct VoiceHeader)) goto pcorrupt;
  417.             if(readbufferfile(h,&vhdr,len1)!=len1) goto perr;
  418.             ifflen-=len1;
  419.             fvhdr=1;
  420.             break;
  421.             default:
  422.             if (len1&1) len1++;
  423.             if (seek(h,len1,OFFSET_CURRENT)<0) goto perr;
  424.             ifflen-=len1;
  425.             break;
  426.         }
  427.     }        
  428.     if(!fvhdr) goto pcorrupt;
  429. } else {
  430.     ifflen=h->size;
  431.     if(seek(h,0,OFFSET_BEGINNING)<0) goto perr;
  432. }
  433. if(!iff||sconfig->askhz) {
  434.     gb=getguibase(cmc->label);
  435.     setconnectgroup(gb,1,0,0);
  436.     reqinfomsg(gb,MSG_AUDIO_ASKFREQUENCY,100,guiUC|guiLEFT);
  437.     reqinteger(gb,100,&value,4000,64000);
  438.     buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  439.     if(!quickreq(gb)) goto perr;
  440.     vhdr.vh_SamplesPerSec=value;
  441. }
  442.  
  443. #ifdef V39
  444. if(GfxBase->DisplayFlags&REALLY_PAL) clock=3546895; else clock=3579545;
  445. #else
  446. if(GfxBase->DisplayFlags&PAL) clock=3546895; else clock=3579545;
  447. #endif
  448. sformatmsg(h->owner->fmmessage1,MSG_AUDIO_INFO1,"8SVX",h->filename,h->size,(LONG)vhdr.vh_SamplesPerSec);
  449. fmmessage(h->owner);
  450. period=clock/vhdr.vh_SamplesPerSec;
  451. ptype=sconfig->type;
  452. if(!ptype) {
  453.     ptype=1;
  454.     if(!requestmsg(getstring(MSG_MAIN_REQUEST),MSG_AUDIO_TYPEANSWER1,MSG_AUDIO_TYPEANSWER2,MSG_AUDIO_ASKTYPE)) ptype=2;
  455. }
  456. if(ptype==2)
  457.     smem1=allocvec(h->owner,h->size,MEMF_CHIP);
  458.     else
  459.     smem1=allocvec(h->owner,smemlen,MEMF_CHIP);
  460. if(!smem1) goto perr;
  461. if(ptype==1) {
  462.     smem2=allocvec(h->owner,smemlen,MEMF_CHIP);
  463.     if(!smem2) goto perr;
  464. }
  465. if(!(fmmain.audio=allocaudio(h->owner))) goto perr;
  466. initaudio(chippi,4,period);
  467. playmem=0; totlen=ifflen;
  468. h->owner->flags|=LUPDATEMSG;
  469. if(ptype==1) {
  470.     while(ifflen>0) {
  471.         waitaudio(DOSBase);
  472.         vara=smem1;smem1=smem2;smem2=vara;
  473.         if(smemlen>ifflen) readlen=ifflen; else readlen=smemlen;
  474.         if(readbufferfile(h,smem1,readlen)!=readlen) goto perr;
  475.         ifflen-=readlen;
  476.         playmem+=readlen;
  477.         sformatmsg(h->owner->fmmessage2,MSG_AUDIO_INFO2,playmem,totlen,(WORD)(playmem*100/totlen));
  478.         if(testabort(h->owner)) {
  479.             endaudio();
  480.             if(askabort(h->owner)) {
  481.                 ret=1;
  482.                 break;
  483.             }
  484.             initaudio(chippi,4,period);
  485.         }
  486.         startaudio(smem1,readlen);
  487.         WaitTOF();
  488.         WaitTOF();
  489.     }
  490. } else {
  491.     if(readbufferfile(h,smem1,ifflen)!=ifflen) goto perr;
  492.     while(ifflen>0) {
  493.         if(smemlen>ifflen) readlen=ifflen; else readlen=smemlen;
  494.         sformatmsg(h->owner->fmmessage2,MSG_AUDIO_INFO2,playmem,totlen,(WORD)(playmem*100/totlen));
  495.         fmmessage(h->owner);
  496.         waitaudio(DOSBase);
  497.         ifflen-=readlen;
  498.         if(testabort(h->owner)) {
  499.             endaudio();
  500.             if(askabort(h->owner)) {
  501.                 ret=1;
  502.                 break;
  503.             }
  504.             initaudio(chippi,4,period);
  505.         }
  506.         startaudio(smem1+playmem,readlen);
  507.         WaitTOF();
  508.         WaitTOF();
  509.         playmem+=readlen;
  510.     }
  511. }
  512. h->owner->flags&=~LUPDATEMSG;
  513. if(ret)    {
  514.     initaudio(chippi,4,period);
  515. } else {
  516.     sformatmsg(h->owner->fmmessage2,MSG_AUDIO_INFO2,playmem,totlen,(WORD)(playmem*100/totlen));
  517.     fmmessage(h->owner);
  518. }
  519. waitaudio(DOSBase);
  520. startaudio(chippi,4);
  521. waitaudio(DOSBase);
  522. endaudio();
  523. ret=1;
  524. goto perr;
  525.  
  526. pcorrupt:
  527. requestmsg(h->owner->workname,0,MSG_OK,MSG_AUDIO_CORRUPT8SVX,h->filename);
  528. perr:
  529. endaudio();
  530. freemem(smem1);
  531. freemem(smem2);
  532. freemem(chippi);
  533. freemem(varabuf);
  534. if(fmmain.audio) {
  535.     closedevice((struct IORequest*)fmmain.audio);
  536.     fmmain.audio=0;
  537. }
  538. return(ret);
  539. }
  540.  
  541.  
  542.  
  543. struct IOAudio* allocaudio(struct FMList *list)
  544. {
  545. struct MsgPort *mp;
  546. struct IOAudio *io;
  547. UBYTE whichchan;
  548.  
  549. whichchan=15;
  550. if(mp=CreateMsgPort()) {
  551.     if(io=(struct IOAudio*)CreateIORequest(mp,sizeof(struct IOAudio))) {
  552.         io->ioa_Request.io_Message.mn_Node.ln_Pri=127;
  553.         io->ioa_Request.io_Command=ADCMD_ALLOCATE;
  554.         io->ioa_Request.io_Flags=ADIOF_NOWAIT;
  555.         io->ioa_AllocKey=0;
  556.         io->ioa_Data=&whichchan;
  557.         io->ioa_Length=1;
  558.         if(!OpenDevice(auddev,0,(struct IORequest*)io,0)) return(io);
  559.         DeleteIORequest((struct IOAudio*)io);
  560.     }
  561.     DeleteMsgPort(mp);
  562. }
  563. requestmsg(list->workname,0,MSG_OK,MSG_FMDOS_OPENERR,auddev);
  564. return(0);
  565. }
  566.  
  567. WORD checkoldaudio(struct FMList *l)
  568. {
  569. if(fmmain.audio) {
  570.     requestmsg(l->workname,0,MSG_OK,MSG_AUDIO_NOAUDIO);
  571.     return(1);
  572. }
  573. return(0);
  574. }
  575.  
  576. void *hearconfigdefault(struct CMenuConfig *cmc)
  577. {
  578. struct AudioConfig *config;
  579. WORD ret;
  580.  
  581. ret=allocconfig(cmc,sizeof(struct AudioConfig));
  582. if(ret<0) return(cmc->moreconfig);
  583. if(!ret) return(0);
  584. config=(struct AudioConfig*)cmc->moreconfig;
  585. config->hz=18000;
  586. config->smemlen=40000;
  587. return(cmc->moreconfig);
  588. }
  589.  
  590. WORD hearconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
  591. {
  592. WORD c;
  593. struct AudioConfig *ac;
  594. WORD askhz,playmethod;
  595. LONG freq,buf;
  596.  
  597. ac=getconfig(cmc);
  598. askhz=ac->askhz;
  599. setguigroup(gb,1,0);
  600. reqinfomsg(gb,MSG_AUDIO_CONFIG_ASKHZ,200,guiUC|guiLEFT);
  601. reqinfomsg(gb,MSG_AUDIO_CONFIG_PLAYMETHOD,201,guiUC|guiLEFT);
  602. reqinfomsg(gb,MSG_AUDIO_CONFIG_FREQUENCY,202,guiUC|guiLEFT);
  603. reqinfomsg(gb,MSG_AUDIO_CONFIG_BUFFER,203,guiUC|guiLEFT);
  604. setguigroup(gb,2,0);
  605. reqcycle2msg(gb,200,&askhz);
  606. playmethod=ac->type;
  607. reqcyclemsg(gb,201,&playmethod,MSG_AUDIO_CONFIG_PLAYMETHOD1,MSG_AUDIO_CONFIG_PLAYMETHOD2,MSG_AUDIO_CONFIG_PLAYMETHOD3,0);
  608. freq=ac->hz;
  609. reqinteger(gb,202,&freq,4000,64000);
  610. buf=ac->smemlen;
  611. reqinteger(gb,203,&buf,4000,99999999);
  612. commandanswer(gb);
  613. c=quickreq(gb);
  614. if(c) {
  615.     ac->type=playmethod;
  616.     ac->askhz=askhz;
  617.     ac->smemlen=buf;
  618.     ac->hz=freq;
  619. }
  620. return(c);
  621. }
  622.