BIOS.EnsoniqSound.Mod 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486
  1. (* Version 0.94 *)
  2. (* AUTHOR: Christian Heinzer, heinzerc@student.ethz.ch *)
  3. (* Based on FreeBSDs dev/sound/pci/es137x.c *)
  4. (* The exported procedures implement those of the generic sound driver interface SoundDevices.Mod *)
  5. MODULE EnsoniqSound; (** AUTHOR "chh"; PURPOSE "Ensoniq PCI Sounddriver"; *)
  6. IMPORT SYSTEM, KernelLog, PCI, Objects, Kernel, Machine, Modules, Plugins, SoundDevices;
  7. CONST
  8. Trace = FALSE; (* debug output kernel log *)
  9. Bsize = 25600 * 3; (* size of intern soundbuffer, better > 25600*)
  10. (* Ensoniq registers and content *)
  11. Es1370RegControl = 0;
  12. Es1370RegStatus = 4H;
  13. Es1370RegSerialControl = 20H;
  14. Es1370RegMemPage = 0CH;
  15. Es1371RegCodec = 14H;
  16. Es1371RegLegacy = 18H;
  17. Es1371RegSmprate = 10H;
  18. Es1370RegDac1Scount = 24H;
  19. Es1370RegDac2Scount = 28H;
  20. Es1370RegAdcScount = 2CH;
  21. Es1371SyncRes = 4000H;
  22. Es1371DisSrc = 400000H;
  23. Es1371SrcRamBusy = 800000H; (*Bit 23 *)
  24. EsSmpregDac1 = 70H;
  25. EsSmpregDac2 = 74H;
  26. EsSmpregAdc = 78H;
  27. EsSmpregVolAdc = 6CH;
  28. EsSmpregVolDac1 = 7CH;
  29. EsSmpregVolDac2 = 7EH;
  30. NumMixerChannels = 5; (* maximal number of mixerchannels *)
  31. TYPE
  32. Sample = ARRAY 4 OF CHAR; (* one sample: stereo 16 Bit *)
  33. Bufferlist = RECORD
  34. content : SoundDevices.Buffer;
  35. next : POINTER TO Bufferlist
  36. END;
  37. Listenerlist = RECORD
  38. proc : SoundDevices.MixerChangedProc;
  39. next : POINTER TO Listenerlist
  40. END;
  41. BuffersToReturn = RECORD (* temporary saves the buffers and their listeners that aren't needed any more *)
  42. blistener : SoundDevices.BufferListener;
  43. content : SoundDevices.Buffer;
  44. next : POINTER TO BuffersToReturn
  45. END;
  46. (* make sure that playcopy is not in progress *)
  47. (* make sure QueueBuffer and ReturnAllBuffers can not run parallel *)
  48. BufferObj* = OBJECT
  49. VAR inplaycopy : BOOLEAN;
  50. drv : Driver;
  51. PROCEDURE Setinplaycopy(pc: BOOLEAN);
  52. BEGIN {EXCLUSIVE}
  53. inplaycopy := pc
  54. END Setinplaycopy;
  55. PROCEDURE ReturnAllBuffers(chan: Channel);
  56. BEGIN {EXCLUSIVE}
  57. AWAIT(inplaycopy=FALSE); (*AWAIT(~playcopy);*)
  58. chan.ReturnAllBuffers
  59. END ReturnAllBuffers;
  60. END BufferObj;
  61. MixerChannel*=OBJECT(SoundDevices.MixerChannel)
  62. VAR vol : LONGINT;
  63. muted : BOOLEAN;
  64. name, desc : POINTER TO ARRAY OF CHAR;
  65. reg : LONGINT; (* register of mixerchannel *)
  66. drv : Driver;
  67. PROCEDURE &Constr*(drv: Driver; name, desc : ARRAY OF CHAR; reg : LONGINT);
  68. VAR i : LONGINT;
  69. BEGIN
  70. SELF.drv := drv;
  71. NEW(SELF.name, LEN(name));
  72. FOR i := 0 TO LEN(name)-1 DO
  73. SELF.name^[i] := name[i]
  74. END;
  75. NEW(SELF.desc, LEN(desc));
  76. FOR i := 0 TO LEN(desc)-1 DO
  77. SELF.desc^[i] := desc[i]
  78. END;
  79. SELF.reg := reg;
  80. i := 0;
  81. WHILE (i < NumMixerChannels-1) & (SELF.drv.mixerChannels[i] # NIL) DO
  82. INC(i)
  83. END;
  84. SELF.drv.mixerChannels[i] := SELF
  85. END Constr;
  86. PROCEDURE SetVolume*(vol : LONGINT);
  87. VAR resl : LONGINT;
  88. BEGIN
  89. IF vol > 0FFH THEN SELF.vol := 0FFH END;
  90. IF vol < 0 THEN SELF.vol := 0 END;
  91. SELF.vol := vol;
  92. resl := 31-SELF.vol DIV 8;
  93. resl := resl+256*resl;
  94. drv.EsWrCd(reg, SYSTEM.VAL(INTEGER, resl));
  95. CallListener
  96. END SetVolume;
  97. PROCEDURE GetVolume*() : LONGINT;
  98. BEGIN
  99. RETURN(vol)
  100. END GetVolume;
  101. PROCEDURE GetIsMute*(): BOOLEAN;
  102. BEGIN
  103. RETURN muted
  104. END GetIsMute;
  105. PROCEDURE CallListener;
  106. VAR nl : POINTER TO Listenerlist;
  107. BEGIN
  108. IF drv.listenerlist # NIL THEN
  109. nl := drv.listenerlist;
  110. WHILE nl.next # NIL DO
  111. IF nl.proc # NIL THEN
  112. nl.proc(SELF)
  113. END;
  114. nl := nl.next
  115. END;
  116. IF nl.proc # NIL THEN
  117. nl.proc(SELF)
  118. END
  119. END
  120. END CallListener;
  121. PROCEDURE GetName*(VAR name: ARRAY OF CHAR);
  122. BEGIN
  123. COPY(SELF.name^, name)
  124. END GetName;
  125. PROCEDURE GetDesc*(VAR desc: ARRAY OF CHAR);
  126. BEGIN
  127. COPY (SELF.desc^, desc)
  128. END GetDesc;
  129. PROCEDURE SetMute*(muted: BOOLEAN);
  130. BEGIN
  131. IF SELF.muted # muted THEN (* change mute state *)
  132. IF muted THEN
  133. drv.EsWrCd(reg, SYSTEM.VAL(INTEGER, 8000H))
  134. ELSE
  135. SetVolume(vol)
  136. END;
  137. SELF.muted := muted;
  138. CallListener
  139. END
  140. END SetMute;
  141. END MixerChannel;
  142. PlayMixerChannel=OBJECT(MixerChannel)
  143. PROCEDURE SetVolume*(vol: LONGINT);
  144. VAR resl : LONGINT;
  145. BEGIN
  146. IF vol > 0FFH THEN vol := 0FFH END;
  147. IF vol < 0 THEN vol := 0 END;
  148. SELF.vol := vol;
  149. resl := 63-vol DIV 4;
  150. resl := resl+256*resl;
  151. drv.EsWrCd(reg, SYSTEM.VAL(INTEGER, resl)); (* Master Out *)
  152. CallListener
  153. END SetVolume;
  154. END PlayMixerChannel;
  155. RecMixerChannel=OBJECT(MixerChannel)
  156. PROCEDURE SetVolume*(vol: LONGINT);
  157. VAR resl : LONGINT;
  158. BEGIN
  159. IF vol > 0FFH THEN vol := 0FFH END;
  160. IF vol < 0 THEN vol := 0 END;
  161. SELF.vol := vol;
  162. resl := vol DIV 16;
  163. resl := resl+256*resl;
  164. drv.EsWrCd(reg, SYSTEM.VAL(INTEGER, resl)); (* Record Gain *)
  165. CallListener
  166. END SetVolume;
  167. END RecMixerChannel;
  168. Channel*=OBJECT(SoundDevices.Channel)
  169. VAR active, free: BOOLEAN;
  170. first, last: POINTER TO Bufferlist; (* fast access to buffers *)
  171. blistener : SoundDevices.BufferListener;
  172. vol : INTEGER;
  173. ratedone : LONGINT; (* for sample rate conversion *)
  174. pos : LONGINT; (* actual position in buffer *)
  175. samplingRate, samplingResolution, nofSubChannels: LONGINT;
  176. delta: LONGINT; (* number of bytes for one sample *)
  177. drv : Driver;
  178. pause, stop, start : BOOLEAN;
  179. silent, rsilent : BOOLEAN; (* is a channel playing/recording? *)
  180. PROCEDURE ReturnAllBuffers;
  181. VAR driver : POINTER TO Bufferlist;
  182. BEGIN
  183. driver := first;
  184. WHILE driver#NIL DO
  185. drv.AddBufferToReturn(blistener, driver.content); (* triggers blistener(driver.content); *)
  186. driver := driver.next
  187. END;
  188. first := NIL; last := NIL
  189. END ReturnAllBuffers;
  190. PROCEDURE &Init*(drv : Driver);
  191. BEGIN
  192. SELF.drv := drv;
  193. pause := FALSE; stop := FALSE; start := FALSE
  194. END Init;
  195. PROCEDURE SetVolume*(vol: LONGINT);
  196. (* standard : 100H *)
  197. BEGIN
  198. IF vol > 0FFFFH THEN vol := 0FFFFH; END;
  199. IF vol < 0 THEN vol := 0; END;
  200. SELF.vol := SHORT(vol)
  201. END SetVolume;
  202. PROCEDURE GetVolume*() : LONGINT;
  203. BEGIN
  204. RETURN vol
  205. END GetVolume;
  206. PROCEDURE GetPosition() : LONGINT;
  207. BEGIN
  208. RETURN pos
  209. END GetPosition;
  210. PROCEDURE Pause*; (* generic pause, used by recordchannel *)
  211. BEGIN {EXCLUSIVE}
  212. active := FALSE
  213. END Pause;
  214. PROCEDURE PauseNonExclusive;
  215. BEGIN
  216. active := FALSE
  217. END PauseNonExclusive;
  218. PROCEDURE Close*;
  219. BEGIN
  220. Stop;
  221. free := TRUE
  222. END Close;
  223. PROCEDURE RegisterBufferListener*(blistener: SoundDevices.BufferListener);
  224. BEGIN
  225. SELF.blistener := blistener
  226. END RegisterBufferListener;
  227. END Channel;
  228. PlayerChannel=OBJECT(Channel)
  229. VAR sample, oldsample : Sample; (*both needed for linear interpolation*)
  230. PROCEDURE Pause*;
  231. BEGIN {EXCLUSIVE}
  232. pause := TRUE (* triggers drv.introbj.Deactivate(SELF) *)
  233. END Pause;
  234. PROCEDURE PauseNonExclusive;
  235. BEGIN
  236. drv.introbj.Deactivate(SELF)
  237. END PauseNonExclusive;
  238. PROCEDURE Stop*;
  239. BEGIN {EXCLUSIVE}
  240. stop := TRUE
  241. END Stop;
  242. PROCEDURE QueueBuffer*(buf: SoundDevices.Buffer);
  243. VAR bufferlist: POINTER TO Bufferlist;
  244. BEGIN {EXCLUSIVE}
  245. IF last # NIL THEN
  246. NEW(bufferlist);
  247. last.next := bufferlist;
  248. bufferlist.next := NIL;
  249. bufferlist.content := buf;
  250. last := bufferlist
  251. ELSE
  252. NEW(bufferlist);
  253. last := bufferlist;
  254. last.next := NIL;
  255. bufferlist.content := buf;
  256. (*I'm too lazy to read in here the very first sample*)
  257. sample[0] := CHR(0); sample[1] := CHR(0);
  258. sample[2] := CHR(0); sample[3] := CHR(0);
  259. (*Take the second sample next for linear interpolation*)
  260. ratedone := 48000-samplingRate;
  261. pos := 0
  262. END;
  263. IF first = NIL THEN first := bufferlist END
  264. END QueueBuffer;
  265. (* Advance by one Buffer *)
  266. PROCEDURE NextBuffer;
  267. BEGIN {EXCLUSIVE}
  268. IF first # NIL THEN
  269. IF first.next # NIL THEN
  270. first := first.next
  271. ELSE
  272. silent := TRUE; active := FALSE;
  273. DEC(drv.introbj.numplayer);
  274. first := NIL
  275. END
  276. END
  277. END NextBuffer;
  278. PROCEDURE Start*;
  279. BEGIN {EXCLUSIVE}
  280. start := TRUE
  281. END Start;
  282. PROCEDURE AwaitEvent;
  283. BEGIN {EXCLUSIVE}
  284. AWAIT(pause OR start OR stop)
  285. END AwaitEvent;
  286. BEGIN {ACTIVE}
  287. REPEAT
  288. AwaitEvent;
  289. IF pause THEN
  290. drv.introbj.Deactivate(SELF); pause := FALSE
  291. END;
  292. IF stop THEN
  293. drv.introbj.Deactivate(SELF);
  294. drv.bufferobj.ReturnAllBuffers(SELF);
  295. stop := FALSE
  296. END;
  297. IF start THEN
  298. IF (first#NIL) THEN (* at least one buffer is registered *)
  299. drv.introbj.Activate(SELF)
  300. END;
  301. start := FALSE
  302. END
  303. UNTIL 1=2
  304. END PlayerChannel;
  305. RecordChannel=OBJECT(Channel)
  306. PROCEDURE Stop*;
  307. BEGIN {EXCLUSIVE}
  308. PauseNonExclusive;
  309. drv.introbj.WaitNoRec;(*AWAIT(~reccopy);*)
  310. drv.bufferobj.ReturnAllBuffers(SELF)
  311. END Stop;
  312. PROCEDURE QueueBuffer*(buf: SoundDevices.Buffer);
  313. VAR bufferlist: POINTER TO Bufferlist;
  314. BEGIN
  315. IF last # NIL THEN
  316. NEW(bufferlist);
  317. last.next := bufferlist;
  318. bufferlist.next := NIL;
  319. bufferlist.content := buf;
  320. last := bufferlist
  321. ELSE
  322. NEW(bufferlist);
  323. last := bufferlist;
  324. last.next := NIL;
  325. bufferlist.content := buf;
  326. ratedone := 0;
  327. pos := 0
  328. END;
  329. IF first = NIL THEN first := bufferlist END
  330. END QueueBuffer;
  331. (* Advances by one Buffer *)
  332. PROCEDURE NextBuffer;
  333. BEGIN {EXCLUSIVE}
  334. IF first.next # NIL THEN
  335. first := first.next
  336. ELSE
  337. rsilent := TRUE; active := FALSE;
  338. first := NIL
  339. END
  340. END NextBuffer;
  341. PROCEDURE Start;
  342. BEGIN {EXCLUSIVE}
  343. IF first#NIL THEN (* at least one buffer registered *)
  344. active := TRUE;
  345. IF ~ (4 IN SYSTEM.VAL(SET, drv.EsState.rctrl)) THEN
  346. IF Trace THEN KernelLog.String("Enabling ADC Interrupt"); END;
  347. drv.rloopcount := 0;
  348. Machine.Portout8(drv.base+Es1370RegMemPage, 0DX); (*1101*)
  349. Machine.Portout32(drv.base+34H, SYSTEM.VAL(LONGINT, Bsize DIV 4-1));
  350. (*additionally resets the counter of transfered longwords to 0*)
  351. drv.EsState.rctrl := SYSTEM.VAL(LONGINT, {4}+SYSTEM.VAL(SET, drv.EsState.rctrl));
  352. Machine.Portout32(drv.base+Es1370RegControl, drv.EsState.rctrl) (*AdcEn*)
  353. END
  354. END
  355. END Start;
  356. END RecordChannel;
  357. Driver*=OBJECT(SoundDevices.Driver)
  358. VAR playchannels : ARRAY 32 OF PlayerChannel; (* 32 channels are supported *)
  359. recordchannels : ARRAY 32 OF RecordChannel;
  360. pcm, line, cd : MixerChannel;
  361. time: Kernel.Timer; (* used in init *)
  362. base, irq : LONGINT; (* base address, interrupt nr of soundcard *)
  363. EsState : RECORD (* actual state of the soundcard *)
  364. sctrl : LONGINT; (* serial control register *)
  365. rctrl : LONGINT; (* irq / chip select block *)
  366. END;
  367. p2, pr2 : POINTER TO ARRAY OF CHAR; (* points to intern soundbuffer for play/record *)
  368. loopcount, rloopcount : LONGINT; (* determines if first or second bufferpart is playing *)
  369. next: Driver;
  370. introbj : Introbj; (* interrupt handler *)
  371. masterout : PlayMixerChannel;
  372. masterin : RecMixerChannel;
  373. allsilent, rallsilent : BOOLEAN; (* is at least one channel playing/recording? *)
  374. playcopy, reccopy : BOOLEAN; (* interrupt occured, copy data *)
  375. listenerlist : POINTER TO Listenerlist; (* list of MixerChangedProc *)
  376. mixerChannels : ARRAY NumMixerChannels OF MixerChannel;
  377. buffersToReturn, lastbtr : POINTER TO BuffersToReturn;
  378. bufferobj : BufferObj;
  379. (** Change the Record Source*)
  380. (** 0: Microphone, 1: CD IN, 4: LINE IN, 5: STEREO MIX (DEFAULT) *)
  381. PROCEDURE SetRecordSource*(i: INTEGER);
  382. BEGIN
  383. EsWrCd(1AH, SYSTEM.VAL(INTEGER, i+i*256))
  384. END SetRecordSource;
  385. PROCEDURE &Constructor*(irq, base: LONGINT);
  386. BEGIN
  387. NEW(bufferobj);
  388. buffersToReturn := NIL;
  389. lastbtr := NIL;
  390. SELF.base := base;
  391. SELF.irq := irq;
  392. SELF.next := installedDrivers;
  393. installedDrivers := SELF;
  394. INC(installed);
  395. Init
  396. END Constructor;
  397. (* add a buffer and it's listener to be returned *)
  398. (* mustn't be EXCLUSIVE because it could be blocked by ReturnBuffers *)
  399. PROCEDURE AddBufferToReturn(blistener: SoundDevices.BufferListener; content: SoundDevices.Buffer);
  400. VAR newbtr : POINTER TO BuffersToReturn;
  401. BEGIN {EXCLUSIVE}
  402. NEW(newbtr);
  403. newbtr.blistener := blistener;
  404. newbtr.content := content;
  405. newbtr.next := NIL;
  406. IF buffersToReturn # NIL THEN lastbtr.next := newbtr; lastbtr := newbtr
  407. ELSE buffersToReturn := newbtr; lastbtr := buffersToReturn END
  408. END AddBufferToReturn;
  409. (* return all collected buffers now *)
  410. PROCEDURE ReturnBuffers;
  411. BEGIN {EXCLUSIVE}
  412. WHILE buffersToReturn # NIL DO
  413. buffersToReturn.blistener(buffersToReturn.content);
  414. buffersToReturn := buffersToReturn.next
  415. END
  416. END ReturnBuffers;
  417. PROCEDURE WaitBuffersToReturn;
  418. BEGIN {EXCLUSIVE}
  419. AWAIT(buffersToReturn # NIL)
  420. END WaitBuffersToReturn;
  421. (* wait until sample rate converter is ready to accept commands/data *)
  422. PROCEDURE EsWaitSrcReady() : LONGINT;
  423. VAR t, r : LONGINT;
  424. BEGIN
  425. FOR t := 0 TO 500 DO
  426. Machine.Portin32(base+Es1371RegSmprate, SYSTEM.VAL(LONGINT, r));
  427. IF ~(23 IN SYSTEM.VAL(SET, r)) THEN
  428. RETURN r
  429. END
  430. END;
  431. KernelLog.String("es1371: wait src ready timeout");
  432. RETURN 0
  433. END EsWaitSrcReady;
  434. (* set the address part of the value for the sample rate converter *)
  435. PROCEDURE EsSrcRamAddro(reg: LONGINT): SET;
  436. VAR s, s2 : SET;
  437. i : LONGINT;
  438. BEGIN
  439. s := SYSTEM.VAL(SET, reg);
  440. s := s*{0..6};
  441. s2 := {};
  442. FOR i := 0 TO 6 DO
  443. IF i IN s THEN s2 := s2+{i+25} END
  444. END;
  445. RETURN s2
  446. END EsSrcRamAddro;
  447. (* set the data part of the value for the src *)
  448. PROCEDURE EsSrcRamDatao(reg: LONGINT): SET;
  449. VAR s : SET;
  450. BEGIN
  451. s := SYSTEM.VAL(SET, reg);
  452. s := s*{0..15};
  453. RETURN s
  454. END EsSrcRamDatao;
  455. (* write to the sample rate converter *)
  456. PROCEDURE EsSrcWrite(reg, data: LONGINT);
  457. VAR r : LONGINT;
  458. VAR s : SET;
  459. BEGIN
  460. r := EsWaitSrcReady();
  461. s := SYSTEM.VAL(SET, r);
  462. s := s * {19..22};
  463. s := s + EsSrcRamAddro(reg)+EsSrcRamDatao(data);
  464. s := s + {24};
  465. r := SYSTEM.VAL(LONGINT, s);
  466. Machine.Portout32(base+Es1371RegSmprate, r)
  467. END EsSrcWrite;
  468. (* read from sample rate converter *)
  469. PROCEDURE EsSrcRead(reg: LONGINT) : LONGINT;
  470. VAR r : LONGINT; s : SET;
  471. BEGIN
  472. r := EsWaitSrcReady();
  473. s := SYSTEM.VAL(SET, r);
  474. s := s*{19..22};
  475. s := s + EsSrcRamAddro(reg);
  476. r := SYSTEM.VAL(LONGINT, r);
  477. Machine.Portout32(base+Es1371RegSmprate, r);
  478. r := EsWaitSrcReady();
  479. RETURN SYSTEM.VAL(LONGINT, EsSrcRamDatao(r))
  480. END EsSrcRead;
  481. (* set the adc sample rate *)
  482. PROCEDURE EsAdcRate(rate, set: LONGINT);
  483. VAR n, truncm, freq, result, tmp : LONGINT;
  484. stmp : SET;
  485. BEGIN
  486. IF rate > 48000 THEN rate := 48000 END;
  487. IF rate < 4000 THEN rate := 4000 END;
  488. n := rate DIV 3000;
  489. IF ((n=15) OR (n=13) OR (n=11) OR (n=9)) THEN DEC(n) END;
  490. truncm := (21*n-1);
  491. truncm := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, truncm)+{0});
  492. freq := ((48000*32768) DIV rate) * n;
  493. result := ((48000*32768) DIV (freq DIV n));
  494. IF set>0 THEN
  495. IF (rate >= 24000) THEN
  496. IF (truncm > 239) THEN truncm := 239; END;
  497. tmp := ((239-truncm) DIV 2) * 512;
  498. stmp := SYSTEM.VAL(SET, tmp) + SYSTEM.VAL(SET, n*16);
  499. tmp := SYSTEM.VAL(LONGINT, stmp);
  500. EsSrcWrite(EsSmpregAdc, tmp)
  501. ELSE
  502. IF (truncm < 119) THEN truncm := 119; END;
  503. tmp := ((119-truncm) DIV 2) * 512;
  504. stmp := SYSTEM.VAL(SET, tmp)+SYSTEM.VAL(SET, n*16)+{15};
  505. tmp := SYSTEM.VAL(LONGINT, stmp);
  506. EsSrcWrite(EsSmpregAdc, tmp)
  507. END;
  508. tmp := EsSrcRead(EsSmpregAdc+1);
  509. stmp := SYSTEM.VAL(SET, tmp)*{0..7};
  510. stmp := stmp + (SYSTEM.VAL(SET, freq DIV 32)*{10..15});
  511. EsSrcWrite(EsSmpregAdc+1, SYSTEM.VAL(LONGINT, stmp));
  512. EsSrcWrite(EsSmpregAdc+3, SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, freq)*{0..14}));
  513. EsSrcWrite(EsSmpregVolAdc, SYSTEM.VAL(LONGINT, n * 256));
  514. EsSrcWrite(EsSmpregVolAdc+1, SYSTEM.VAL(LONGINT, n * 256))
  515. END
  516. END EsAdcRate;
  517. (* set the dac sample rate for dac number "set" *)
  518. PROCEDURE EsDacRate(rate, set: LONGINT);
  519. VAR freq, r, result, dac, dis, temp : LONGINT;
  520. VAR stmp : SET;
  521. BEGIN
  522. IF rate > 48000 THEN rate := 48000; END;
  523. IF rate < 4000 THEN rate := 4000; END;
  524. freq := (rate * 32768) DIV 3000;
  525. result := (freq * 3000) DIV 32768;
  526. IF set>0 THEN
  527. IF set = 1 THEN dac := EsSmpregDac1; ELSE dac := EsSmpregDac2; END;
  528. IF set = 1 THEN dis := 20; ELSE dis := 21; END;
  529. r := EsWaitSrcReady();
  530. stmp := SYSTEM.VAL(SET, r)*{19..22};
  531. r := SYSTEM.VAL(LONGINT, stmp);
  532. Machine.Portout32(base+Es1371RegSmprate, r);
  533. r := EsSrcRead(dac+1);
  534. stmp := SYSTEM.VAL(SET, r)*{0..7};
  535. stmp := stmp + (SYSTEM.VAL(SET, freq DIV 32)*{10..15});
  536. temp := SYSTEM.VAL(LONGINT, stmp);
  537. EsSrcWrite(dac+1, temp);
  538. stmp := SYSTEM.VAL(SET, freq);
  539. stmp := stmp*{0..14};
  540. temp := SYSTEM.VAL(LONGINT, stmp);
  541. EsSrcWrite(dac+3, temp);
  542. r := EsWaitSrcReady();
  543. stmp := SYSTEM.VAL(SET, r);
  544. stmp := stmp*({22}+{dis}+{19});
  545. r := SYSTEM.VAL(LONGINT, stmp);
  546. Machine.Portout32(base+Es1371RegSmprate, r)
  547. END
  548. END EsDacRate;
  549. (* write ac97 codec *)
  550. PROCEDURE EsWrCd(addr, data: LONGINT);
  551. VAR t, res, x, i: LONGINT;
  552. VAR tset, tset2 : SET;
  553. BEGIN
  554. t := 0;
  555. REPEAT
  556. INC(t);
  557. Machine.Portin32(base+Es1371RegCodec, SYSTEM.VAL(LONGINT, res))
  558. UNTIL ((t>2000) OR ~(30 IN SYSTEM.VAL(SET, res)));
  559. Machine.Portin32(base+Es1371RegSmprate, SYSTEM.VAL(LONGINT, x));
  560. t := EsWaitSrcReady();
  561. t := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, t)*{19..22});
  562. Machine.Portout32(base+Es1371RegSmprate, t);
  563. t := 0;
  564. REPEAT
  565. INC(t);
  566. Machine.Portin32(base+Es1371RegSmprate, SYSTEM.VAL(LONGINT, res))
  567. UNTIL (t>2000) OR (SYSTEM.VAL(SET, res)*{16..18, 23} = {16});
  568. tset := SYSTEM.VAL(SET, addr)*{0..6};
  569. tset2 := {};
  570. FOR i := 0 TO 6 DO
  571. IF i IN tset THEN tset2 := tset2+{i+16} END
  572. END;
  573. tset := SYSTEM.VAL(SET, data)*{0..15};
  574. tset := tset+tset2;
  575. res := SYSTEM.VAL(LONGINT, tset);
  576. Machine.Portout32(base+Es1371RegCodec, res);
  577. t := EsWaitSrcReady();
  578. Machine.Portout32(base+Es1371RegSmprate, x)
  579. END EsWrCd;
  580. (* initialise the driver *)
  581. PROCEDURE Initdrv;
  582. VAR i: LONGINT;
  583. sndbuf : Machine.Address32; (* physical address of the intern soundbuffer *)
  584. BEGIN
  585. FOR i := 0 TO 31 DO
  586. NEW(playchannels[i], SELF);
  587. playchannels[i].active := FALSE;
  588. playchannels[i].free := TRUE
  589. END;
  590. FOR i := 0 TO 31 DO
  591. NEW(recordchannels[i], SELF);
  592. recordchannels[i].active := FALSE;
  593. recordchannels[i].free := TRUE
  594. END;
  595. NEW(introbj, SELF);
  596. introbj.numplayer := 0;
  597. (* set Bit 19 instead if you want to play direct 8 Bit sound *)
  598. EsState.sctrl := SYSTEM.VAL(LONGINT, {20});
  599. EsState.rctrl := 0;
  600. NEW(time);
  601. Objects.InstallHandler(introbj.HandleInterrupt, Machine.IRQ0+irq);
  602. (*********** INIT like in BSD driver *******************************)
  603. Machine.Portout32(base+Es1370RegStatus, SYSTEM.VAL(LONGINT, {29})); (* No idea why this is needed *)
  604. time.Sleep(20);
  605. Machine.Portout32(base+Es1370RegSerialControl, SYSTEM.VAL(LONGINT, 0));
  606. Machine.Portout32(base+Es1371RegLegacy, SYSTEM.VAL(LONGINT, 0));
  607. (* Now not again RegLegacy like in BSD-Driver *)
  608. Machine.Portout32(base+Es1370RegControl, SYSTEM.VAL(LONGINT, Es1371SyncRes));
  609. time.Sleep(2); Machine.Portout32(base+Es1370RegControl, SYSTEM.VAL(LONGINT, {}));
  610. Machine.Portout32(base+Es1371RegSmprate, SYSTEM.VAL(LONGINT, Es1371DisSrc));
  611. FOR i := 0 TO 07FH DO
  612. EsSrcWrite(SYSTEM.VAL(INTEGER, i), 0)
  613. END;
  614. EsSrcWrite(EsSmpregDac1, SYSTEM.VAL(LONGINT, {8}));
  615. EsSrcWrite(EsSmpregDac1+1, SYSTEM.VAL(LONGINT, {14}));
  616. EsSrcWrite(EsSmpregDac2, SYSTEM.VAL(LONGINT, {8}));
  617. EsSrcWrite(EsSmpregDac2+1, SYSTEM.VAL(LONGINT, {14}));
  618. (*Why not?*)
  619. EsSrcWrite(EsSmpregAdc, SYSTEM.VAL(LONGINT, {8}));
  620. EsSrcWrite(EsSmpregAdc+1, SYSTEM.VAL(LONGINT, {14}));
  621. EsSrcWrite(EsSmpregVolAdc, SYSTEM.VAL(LONGINT, {12}));
  622. EsSrcWrite(EsSmpregVolAdc+1, SYSTEM.VAL(LONGINT, {12}));
  623. EsSrcWrite(EsSmpregVolDac1, SYSTEM.VAL(LONGINT, {12}));
  624. EsSrcWrite(EsSmpregVolDac1+1, SYSTEM.VAL(LONGINT, {12}));
  625. EsSrcWrite(EsSmpregVolDac2, SYSTEM.VAL(LONGINT, {12}));
  626. EsSrcWrite(EsSmpregVolDac2+1, SYSTEM.VAL(LONGINT, {12}));
  627. EsAdcRate(48000, 1); (* set the base (hardware) samplerate for recording *)
  628. EsDacRate(48000, 2); (* set the base (hardware) samplerate for playback *)
  629. (*EsDacRate(40100, 1);(* DAC1 is not used in this driver *) *)
  630. Machine.Portout32(base+Es1371RegSmprate, SYSTEM.VAL(LONGINT, 0));
  631. (*****************************************************)
  632. (* allocate, allign and register record and play buffer *)
  633. NEW(pr2, Bsize);
  634. rloopcount := 0;
  635. NEW(p2, Bsize);
  636. loopcount := 0;
  637. Machine.Portout32(base+Es1370RegControl, SYSTEM.VAL(LONGINT, {})); (* Disable all Channels *)
  638. sndbuf := Machine.Ensure32BitAddress (Machine.PhysicalAdr(ADDRESSOF(pr2[0]), Bsize));
  639. IF sndbuf = -1 THEN KernelLog.String("not enough defragmented space"); END;
  640. Machine.Portout8(base+Es1370RegMemPage, 0DX); (*1101*)
  641. Machine.Portout32(base+30H, SYSTEM.VAL(LONGINT, sndbuf)); (* physical buf adress *)
  642. Machine.Portout32(base+34H, SYSTEM.VAL(LONGINT, Bsize DIV 4-1)); (* size of buffer (in longwords -1) *)
  643. (* number of samples to playback until interrupt for ADC*)
  644. (* set it to Bsize DIV 4-1 for 16bitmono/8bitstereo and to Bsize DIV 2-1 for 8bitmono *)
  645. Machine.Portout32(base+Es1370RegAdcScount, SYSTEM.VAL(LONGINT, Bsize DIV 8-1));
  646. (* enable interrupt and set dataformat for ADC*)
  647. (* 14: LoopMode OFF, driver is always in loop mode *)
  648. (* 4,5: 00:8BMono 01:8BStereo 10:16BM 11:16BS *)
  649. (* 10: INTERRUPT ENABLE*)
  650. EsState.sctrl := SYSTEM.VAL(LONGINT, {4, 5, 10}+SYSTEM.VAL(SET, EsState.sctrl));
  651. Machine.Portout32(base+Es1370RegSerialControl, EsState.sctrl);
  652. sndbuf := Machine.Ensure32BitAddress (Machine.PhysicalAdr(ADDRESSOF(p2[0]), Bsize));
  653. IF sndbuf = -1 THEN KernelLog.String("not enough defragmented space") END;
  654. Machine.Portout8(base+Es1370RegMemPage, 0CX); (*1100*)
  655. Machine.Portout32(base+38H, SYSTEM.VAL(LONGINT, sndbuf)); (*physical buf adress*)
  656. Machine.Portout32(base+3CH, SYSTEM.VAL(LONGINT, Bsize DIV 4-1)); (* size of buffer (in longwords -1) *)
  657. (* number of samples to record until interrupt for DAC2*)
  658. (* set it to Bsize DIV 4-1 for 16bitmono/8bitstereo and to Bsize DIV 2-1 for 8bitmono *)
  659. Machine.Portout32(base+Es1370RegDac2Scount, SYSTEM.VAL(LONGINT, Bsize DIV 8-1));
  660. (* enable interrupt and set dataformat for DAC2*)
  661. (*14: LoopMode OFF, driver is always in loop mode*)
  662. (*2,3: 00:8BMono 01:8BStereo 10:16BM 11:16BS *)
  663. (*9: INTERRUPT ENABLE*)
  664. EsState.sctrl := SYSTEM.VAL(LONGINT, {2, 3, 9} + SYSTEM.VAL(SET, EsState.sctrl));
  665. Machine.Portout32(base+Es1370RegSerialControl, EsState.sctrl)
  666. END Initdrv;
  667. PROCEDURE Initvol;
  668. BEGIN
  669. (*EsWrCd(0, 1); (*Reset*) not needed*)
  670. EsWrCd(2, 0000H); (*Master*)
  671. EsWrCd(4, 8000H); (*Aux*)
  672. EsWrCd(6, 8000H); (*Mono*)
  673. EsWrCd(8, 8000H); (*Tone*)
  674. EsWrCd(0CH, 8000H); (*Phone*)
  675. EsWrCd(0EH, 8000H); (*Mic*)
  676. EsWrCd(10H, 4040H); (*Line In*)
  677. EsWrCd(18H, 4040H); (*PCM Out*)
  678. EsWrCd(1AH, SYSTEM.VAL(INTEGER, 5+5*256)); (*Record Source Stereo Mix*)
  679. EsWrCd(1CH, SYSTEM.VAL(INTEGER, 0+0*256)); (*Record Gain*)
  680. EsWrCd(1EH, SYSTEM.VAL(INTEGER, 0)); (*Record Gain Mic*)
  681. (* alternatives:
  682. EsWrCd(1AH, SYSTEM.VAL(INTEGER, 0)); (* Record Source Micro *)
  683. EsWrCd(1CH, SYSTEM.VAL(INTEGER, 15+15*256)); (*Record Gain*)
  684. EsWrCd(1EH, SYSTEM.VAL(INTEGER, 15)); (*Record Gain Mic*)
  685. *)
  686. IF Trace THEN KernelLog.String("Volume initialized"); KernelLog.Ln END
  687. END Initvol;
  688. PROCEDURE Finalize;
  689. BEGIN
  690. (* disable interrupt *)
  691. Machine.Portout32(base+Es1370RegSerialControl, SYSTEM.VAL(LONGINT, {20}));
  692. Objects.RemoveHandler(introbj.HandleInterrupt, Machine.IRQ0+irq);
  693. time.Sleep(100); (* make sure interrup has terminated *)
  694. IF Modules.shutdown = Modules.None THEN
  695. SoundDevices.devices.Remove(SELF)
  696. END
  697. END Finalize;
  698. PROCEDURE Init*;
  699. VAR i : LONGINT;
  700. BEGIN
  701. Initdrv;
  702. Initvol; (* initialise the hardware volume *)
  703. FOR i := 0 TO NumMixerChannels-1 DO mixerChannels[i] := NIL END;
  704. NEW(masterout, SELF, "MasterOut", "Master Output mixer channel", 02H);
  705. NEW(masterin, SELF, "MasterIn", "master Input mixer channel", 1CH);
  706. NEW(pcm, SELF, "PCM", "PCM Output mixer channel", 18H);
  707. NEW(line, SELF, "LineIn", "Line In mixer channel", 10H);
  708. NEW(cd, SELF, "CD", "CD mixer channel", 12H);
  709. masterIn := masterin;
  710. masterOut := masterout;
  711. desc := "Ensoniq PCI Sound driver";
  712. masterin.SetVolume(0H);
  713. masterout.SetVolume(0FFH);
  714. pcm.SetVolume(0D8H);
  715. (* according to documentation pcm.SetVolume(0B8H) should give gain 0, but it's too silent *)
  716. masterin.muted := FALSE;
  717. masterout.muted := FALSE;
  718. pcm.muted := FALSE;
  719. line.SetVolume(0D8H);
  720. (*line.SetMute(TRUE);*) (* set it mute if you hear noise *)
  721. cd.SetVolume(0D8H);
  722. cd.SetMute(TRUE);
  723. (* set volume so that recorded sound gets played back with same amplitude *)
  724. NEW(listenerlist); (* no mixer listeners so far *)
  725. listenerlist.proc := NIL;
  726. listenerlist.next := NIL;
  727. IF Trace THEN KernelLog.String("init done"); KernelLog.Ln END
  728. END Init;
  729. PROCEDURE OpenPlayChannel*(VAR channel : SoundDevices.Channel;
  730. samplingRate, samplingResolution, nofSubChannels, format : LONGINT;
  731. VAR res : WORD);
  732. VAR i, count : LONGINT;
  733. BEGIN {EXCLUSIVE}
  734. channel := NIL;
  735. count := 0;
  736. FOR i := 0 TO 31 DO
  737. IF ~playchannels[i].free THEN
  738. INC(count)
  739. END
  740. END;
  741. IF Trace THEN KernelLog.String("Active channel #: "); KernelLog.Int(count, 0); KernelLog.Ln END;
  742. i := 0;
  743. WHILE (i<=31) & (~playchannels[i].free) DO
  744. INC(i);
  745. END;
  746. IF i <32 THEN
  747. channel := playchannels[i];
  748. playchannels[i].free := FALSE;
  749. playchannels[i].first := NIL;
  750. playchannels[i].last := NIL;
  751. playchannels[i].samplingRate := samplingRate;
  752. playchannels[i].samplingResolution := samplingResolution;
  753. playchannels[i].nofSubChannels := nofSubChannels;
  754. playchannels[i].delta := (samplingResolution DIV 8) * nofSubChannels; (* number of bytes per sample *)
  755. playchannels[i].SetVolume(100H);
  756. playchannels[i].RegisterBufferListener(DefaultBufferListener);
  757. res := SoundDevices.ResOK;
  758. IF Trace THEN KernelLog.String("Open play channel #: "); KernelLog.Int(i, 0); KernelLog.Ln END
  759. ELSE res := SoundDevices.ResNoMoreChannels
  760. END
  761. END OpenPlayChannel;
  762. PROCEDURE OpenRecordChannel*(VAR channel : SoundDevices.Channel;
  763. samplingRate, samplingResolution, nofSubChannels, format : LONGINT;
  764. VAR res: WORD);
  765. VAR i : LONGINT;
  766. BEGIN
  767. channel := NIL;
  768. i := 0;
  769. WHILE (i <= 31) & (~recordchannels[i].free) DO
  770. INC(i)
  771. END;
  772. IF i<32 THEN
  773. channel := recordchannels[i];
  774. recordchannels[i].free := FALSE;
  775. recordchannels[i].first := NIL;
  776. recordchannels[i].last := NIL;
  777. recordchannels[i].samplingRate := samplingRate;
  778. recordchannels[i].samplingResolution := samplingResolution;
  779. recordchannels[i].nofSubChannels := nofSubChannels;
  780. recordchannels[i].delta := (samplingResolution DIV 8) * nofSubChannels; (* number of bytes per sample *)
  781. recordchannels[i].SetVolume(100H);
  782. recordchannels[i].RegisterBufferListener(DefaultBufferListener);
  783. res := SoundDevices.ResOK
  784. ELSE res := SoundDevices.ResNoMoreChannels
  785. END
  786. END OpenRecordChannel;
  787. PROCEDURE NofNativeFrequencies*():LONGINT;
  788. BEGIN
  789. RETURN 1
  790. END NofNativeFrequencies;
  791. PROCEDURE GetNativeFrequency*(nr: LONGINT): LONGINT;
  792. BEGIN
  793. RETURN 48000
  794. END GetNativeFrequency;
  795. PROCEDURE RegisterMixerChangeListener*(mixChangedProc: SoundDevices.MixerChangedProc);
  796. VAR nlistenerlist, nl : POINTER TO Listenerlist;
  797. BEGIN
  798. IF listenerlist.proc = NIL THEN
  799. listenerlist.proc := mixChangedProc
  800. ELSE
  801. nlistenerlist := listenerlist;
  802. WHILE nlistenerlist.next # NIL DO
  803. nlistenerlist := nlistenerlist.next
  804. END;
  805. NEW(nl);
  806. nl.proc := mixChangedProc;
  807. nl.next := NIL;
  808. nlistenerlist.next := nl
  809. END
  810. END RegisterMixerChangeListener;
  811. PROCEDURE UnregisterMixerChangeListener*(mixChangedProc: SoundDevices.MixerChangedProc);
  812. VAR nlistenerlist, nl : POINTER TO Listenerlist;
  813. BEGIN
  814. nlistenerlist := listenerlist;
  815. IF nlistenerlist.proc = mixChangedProc THEN
  816. IF listenerlist.next # NIL THEN listenerlist := listenerlist.next
  817. ELSE
  818. listenerlist.proc := NIL
  819. END
  820. ELSE
  821. WHILE (nlistenerlist.next # NIL) & (nlistenerlist.proc # mixChangedProc) DO
  822. nl := nlistenerlist;
  823. nlistenerlist := nlistenerlist.next
  824. END;
  825. IF nlistenerlist.proc=mixChangedProc THEN
  826. nl.next := nlistenerlist.next
  827. END
  828. END
  829. END UnregisterMixerChangeListener;
  830. PROCEDURE GetMixerChannel*(channelNr: LONGINT; VAR channel: SoundDevices.MixerChannel);
  831. BEGIN
  832. IF (channelNr<NumMixerChannels) & (channelNr>=0) THEN
  833. channel := (mixerChannels[channelNr])
  834. ELSE
  835. channel := NIL
  836. END;
  837. END GetMixerChannel;
  838. PROCEDURE GetNofMixerChannels*() : LONGINT;
  839. BEGIN
  840. RETURN NumMixerChannels
  841. END GetNofMixerChannels;
  842. BEGIN {ACTIVE}
  843. REPEAT
  844. WaitBuffersToReturn;
  845. ReturnBuffers
  846. UNTIL 1=2
  847. END Driver;
  848. (* interrupt handling Object *)
  849. Introbj=OBJECT
  850. VAR numplayer : LONGINT;
  851. driver : Driver;
  852. VAR copy : BOOLEAN;
  853. PROCEDURE &Init*(driver : Driver);
  854. BEGIN
  855. SELF.driver := driver;
  856. copy := FALSE
  857. END Init;
  858. PROCEDURE WaitInterruptStop;
  859. BEGIN
  860. AWAIT(~(5 IN SYSTEM.VAL(SET, driver.EsState.rctrl)))
  861. END WaitInterruptStop;
  862. PROCEDURE Deactivate(playerchannel : PlayerChannel);
  863. BEGIN {EXCLUSIVE}
  864. IF playerchannel.active THEN
  865. playerchannel.active := FALSE;
  866. DEC(numplayer);
  867. IF numplayer=0 THEN
  868. WaitInterruptStop
  869. END
  870. END
  871. END Deactivate;
  872. PROCEDURE Activate(playerchannel : PlayerChannel);
  873. BEGIN {EXCLUSIVE}
  874. IF playerchannel.active = FALSE THEN
  875. IF numplayer=0 THEN
  876. WaitInterruptStop;
  877. (*Make sure Interrupt is already disabled*)
  878. driver.playcopy := TRUE;
  879. driver.loopcount := 1
  880. END;
  881. playerchannel.active := TRUE;
  882. INC(numplayer)
  883. END
  884. END Activate;
  885. PROCEDURE HandleInterrupt; (* interrupt handler *)
  886. VAR r, where : LONGINT;
  887. sr, ssctrl : SET;
  888. BEGIN {EXCLUSIVE}
  889. Machine.Portin32(driver.base+Es1370RegStatus, r);
  890. sr := SYSTEM.VAL(SET, r);
  891. IF 31 IN sr THEN (* Interrupt pending *)
  892. IF 0 IN sr THEN (* ACD int pending *)
  893. Machine.Portout8(driver.base+Es1370RegMemPage, 0DX);
  894. Machine.Portin32(driver.base+34H, where);
  895. IF where DIV 65536 >= Bsize DIV 8 -1 THEN
  896. driver.rloopcount := 0 ELSE driver.rloopcount := 1
  897. END; (* which part of the buffer is not getting recorded into, so we can read it out next*)
  898. driver.reccopy := TRUE;
  899. ssctrl := SYSTEM.VAL(SET, driver.EsState.sctrl)-{10};
  900. Machine.Portout32(driver.base+Es1370RegSerialControl, SYSTEM.VAL(LONGINT, ssctrl));
  901. Machine.Portout32(driver.base+Es1370RegSerialControl, driver.EsState.sctrl)
  902. END;
  903. IF 1 IN sr THEN (* DAC2 int pending *)
  904. Machine.Portout8(driver.base+Es1370RegMemPage, 0CX);
  905. Machine.Portin32(driver.base+3CH, where);
  906. IF where DIV 65536 >= Bsize DIV 8 - 1 THEN
  907. driver.loopcount := 0 ELSE driver.loopcount := 1;
  908. END; (* which part of the buffer is not playing, so we can fill it next*)
  909. driver.playcopy := TRUE;
  910. ssctrl := SYSTEM.VAL(SET, driver.EsState.sctrl)-{9};
  911. Machine.Portout32(driver.base+Es1370RegSerialControl, SYSTEM.VAL(LONGINT, ssctrl));
  912. Machine.Portout32(driver.base+Es1370RegSerialControl, driver.EsState.sctrl)
  913. END;
  914. IF 2 IN sr THEN (* DAC1 int pending, should never happen *)
  915. ssctrl := SYSTEM.VAL(SET, driver.EsState.sctrl)-{8};
  916. Machine.Portout32(driver.base+Es1370RegSerialControl, SYSTEM.VAL(LONGINT, ssctrl));
  917. Machine.Portout32(driver.base+Es1370RegSerialControl, driver.EsState.sctrl)
  918. END
  919. END
  920. END HandleInterrupt;
  921. (* wait until interrupt sets playcopy or reccopy *)
  922. PROCEDURE Wait;
  923. BEGIN {EXCLUSIVE}
  924. AWAIT(driver.playcopy OR driver.reccopy)
  925. END Wait;
  926. PROCEDURE WaitNoPlay;
  927. BEGIN {EXCLUSIVE}
  928. AWAIT(~driver.playcopy);
  929. END WaitNoPlay;
  930. PROCEDURE WaitNoRec;
  931. BEGIN (*{EXCLUSIVE}*)
  932. AWAIT(~driver.reccopy)
  933. END WaitNoRec;
  934. PROCEDURE Setplaycopy(VALUE: BOOLEAN);
  935. BEGIN {EXCLUSIVE}
  936. driver.playcopy := VALUE
  937. END Setplaycopy;
  938. (* make sure amplitude is in the allowed range *)
  939. PROCEDURE Clip(VAR lsigned: LONGINT);
  940. BEGIN
  941. IF lsigned >MAX(INTEGER) THEN
  942. lsigned := MAX(INTEGER)
  943. END;
  944. IF lsigned <MIN(INTEGER) THEN
  945. lsigned := MIN(INTEGER)
  946. END
  947. END Clip;
  948. PROCEDURE Copy;
  949. VAR first : BOOLEAN;
  950. (* convert sample from mono to stereo *)
  951. PROCEDURE mono(VAR ca: Sample);
  952. BEGIN
  953. ca[2] := ca[0];
  954. ca[3] := ca[1]
  955. END mono;
  956. (* convert sample from 8 to 16 bit *)
  957. PROCEDURE eight(VAR ca: Sample);
  958. BEGIN
  959. ca[3] := CHR(ORD(ca[1])-128);
  960. ca[2] := CHR(0);
  961. ca[1] := CHR(ORD(ca[0])-128);
  962. ca[0] := CHR(0)
  963. END eight;
  964. (* convert 8 bit mono sample to 16 bit stereo *)
  965. PROCEDURE eightmono(VAR ca: Sample);
  966. BEGIN
  967. eight(ca);
  968. mono(ca)
  969. END eightmono;
  970. (* fills first or second half of intern buffer *)
  971. PROCEDURE Playcopy(from, to : LONGINT);
  972. VAR signed : INTEGER;
  973. lsigned, i, j, l : LONGINT;
  974. nr : LONGINT; (* ratedone MOD 48000 *)
  975. temp : LONGINT;
  976. PROCEDURE Readnextsample;
  977. BEGIN
  978. driver.playchannels[j].pos := driver.playchannels[j].pos+driver.playchannels[j].delta;
  979. driver.playchannels[j].ratedone := nr;
  980. driver.playchannels[j].oldsample := driver.playchannels[j].sample;
  981. (* first should never be NIL if we get so far. but if we are unlucky -stop and play of a channel exactly after each other- it can be, drop me a mail if you see how *)
  982. IF (driver.playchannels[j].first # NIL) & (driver.playchannels[j].pos >= driver.playchannels[j].first.content.len) THEN
  983. (* current buffer is over *)
  984. driver.playchannels[j].pos := 0;
  985. (* driver.playchannels[j].blistener(driver.playchannels[j].first.content); *)
  986. (* can't return the buffer directly because we are inside an EXCLUSIVE part here and don't want
  987. to call an external Procedure from here, so save it for later in bufferObj *)
  988. driver.AddBufferToReturn(driver.playchannels[j].blistener, driver.playchannels[j].first.content);
  989. driver.playchannels[j].NextBuffer;
  990. END;
  991. IF (driver.playchannels[j].silent) OR (driver.playchannels[j].first = NIL) THEN (* nothing more to read, but will still interpolate with oldsample *)
  992. driver.playchannels[j].sample[0]:= CHR(0);
  993. driver.playchannels[j].sample[1]:= CHR(0);
  994. driver.playchannels[j].sample[2]:= CHR(0);
  995. driver.playchannels[j].sample[3]:= CHR(0)
  996. ELSE
  997. driver.allsilent := FALSE;
  998. (* convert sample to 16 bit stereo *)
  999. driver.playchannels[j].sample[0] :=
  1000. driver.playchannels[j].first.content.data[driver.playchannels[j].pos];
  1001. IF (driver.playchannels[j].samplingResolution=8) &
  1002. (driver.playchannels[j].nofSubChannels=1) THEN
  1003. eightmono(driver.playchannels[j].sample)
  1004. END;
  1005. IF (driver.playchannels[j].samplingResolution=16) OR
  1006. (driver.playchannels[j].nofSubChannels=2) THEN
  1007. driver.playchannels[j].sample[1] :=
  1008. driver.playchannels[j].first.content.data[driver.playchannels[j].pos+1];
  1009. IF (driver.playchannels[j].samplingResolution=8) THEN
  1010. eight(driver.playchannels[j].sample)
  1011. END;
  1012. IF (driver.playchannels[j].nofSubChannels=1) THEN
  1013. mono(driver.playchannels[j].sample)
  1014. END;
  1015. IF (driver.playchannels[j].samplingResolution=16) &
  1016. (driver.playchannels[j].nofSubChannels=2) THEN
  1017. driver.playchannels[j].sample[2] :=
  1018. driver.playchannels[j].first.content.data[driver.playchannels[j].pos+2];
  1019. driver.playchannels[j].sample[3] :=
  1020. driver.playchannels[j].first.content.data[driver.playchannels[j].pos+3]
  1021. END
  1022. END
  1023. END (* not silent *)
  1024. END Readnextsample;
  1025. BEGIN {EXCLUSIVE}
  1026. driver.bufferobj.Setinplaycopy(TRUE); (* wait until bufferobj is not locked *)
  1027. FOR j := 0 TO 31 DO
  1028. IF driver.playchannels[j].active THEN
  1029. driver.playchannels[j].silent := FALSE;
  1030. i := from;
  1031. WHILE (i <= to) DO
  1032. driver.playchannels[j].ratedone :=
  1033. driver.playchannels[j].ratedone + driver.playchannels[j].samplingRate;
  1034. nr := driver.playchannels[j].ratedone MOD 48000;
  1035. IF (nr # driver.playchannels[j].ratedone) THEN
  1036. IF (driver.playchannels[j].active) THEN
  1037. (* time to read out next sample *)
  1038. Readnextsample
  1039. ELSE
  1040. driver.playchannels[j].oldsample[0] := CHR(0);
  1041. driver.playchannels[j].oldsample[1] := CHR(0);
  1042. driver.playchannels[j].oldsample[2] := CHR(0);
  1043. driver.playchannels[j].oldsample[3] := CHR(0)
  1044. (* now it's really silent *)
  1045. END
  1046. END;
  1047. IF first THEN (* don't have to mix *)
  1048. FOR l := 0 TO 1 DO
  1049. signed := SYSTEM.VAL(INTEGER, driver.playchannels[j].sample[2*l]);
  1050. lsigned := LONG(signed);
  1051. signed := SYSTEM.VAL(INTEGER, driver.playchannels[j].oldsample[2*l]);
  1052. lsigned := ENTIER((1-driver.playchannels[j].ratedone/48000)*
  1053. LONG(signed)+(driver.playchannels[j].ratedone/48000)*lsigned+0.5);
  1054. lsigned := lsigned*(driver.playchannels[j].vol) DIV 256 (*DIV 32*);
  1055. Clip(lsigned);
  1056. signed := SHORT(lsigned);
  1057. driver.p2[i+2*l] := CHR(signed MOD 256);
  1058. driver.p2[i+2*l+1] := CHR(signed DIV 256)
  1059. END
  1060. ELSE (* mix with current buffercontent *)
  1061. FOR l := 0 TO 1 DO
  1062. signed := SYSTEM.VAL(INTEGER, driver.playchannels[j].sample[2*l]);
  1063. lsigned := LONG(signed);
  1064. signed := SYSTEM.VAL(INTEGER, driver.playchannels[j].oldsample[2*l]);
  1065. lsigned := ENTIER((1-driver.playchannels[j].ratedone/48000)*
  1066. LONG(signed)+(driver.playchannels[j].ratedone/48000)*lsigned+0.5);
  1067. lsigned := lsigned*(driver.playchannels[j].vol) DIV 256 (*DIV 32*);
  1068. signed := SYSTEM.VAL(INTEGER, driver.p2[i+2*l]);
  1069. lsigned := LONG(signed) + lsigned;
  1070. Clip(lsigned);
  1071. signed := SHORT(lsigned);
  1072. driver.p2[i+2*l] := CHR(signed MOD 256);
  1073. driver.p2[i+1+2*l] := CHR(signed DIV 256)
  1074. END
  1075. END;
  1076. INC(i, 4)
  1077. END; (*WHILE*)
  1078. first := FALSE (* next channel can't be the first *)
  1079. END (*IF*)
  1080. END; (*FOR*)
  1081. IF ~driver.allsilent THEN (* make sure playing is in progress *)
  1082. IF ~ (5 IN SYSTEM.VAL(SET, driver.EsState.rctrl)) THEN
  1083. IF Trace THEN KernelLog.String("Enabling DAC2 Interrupt"); KernelLog.Ln END;
  1084. Machine.Portout8(driver.base+Es1370RegMemPage, 0CX); (*1100*)
  1085. Machine.Portout32(driver.base+3CH, SYSTEM.VAL(LONGINT, Bsize DIV 4-1));
  1086. (*resets the counter of transferred longwords to 0*)
  1087. driver.EsState.rctrl := SYSTEM.VAL(LONGINT, {5}+SYSTEM.VAL(SET, driver.EsState.rctrl));
  1088. Machine.Portout32(driver.base+Es1370RegControl, driver.EsState.rctrl); (*Dac2En*)
  1089. END;
  1090. ELSE (* make sure playing is stopped *)
  1091. IF (5 IN SYSTEM.VAL(SET, driver.EsState.rctrl)) THEN
  1092. temp := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, driver.EsState.rctrl)-{5});
  1093. Machine.Portout32(driver.base+Es1370RegControl, temp); (*Dac2Dis*)
  1094. FOR i := 0 TO Bsize-1 DO driver.p2[i] := CHR(0) END;
  1095. driver.EsState.rctrl := temp
  1096. END
  1097. END;
  1098. driver.bufferobj.Setinplaycopy(FALSE)
  1099. END Playcopy;
  1100. PROCEDURE Reccopy(from, to: LONGINT);
  1101. VAR sample : Sample;
  1102. signed : INTEGER;
  1103. lsigned, i, j, l : LONGINT;
  1104. nr : LONGINT; (* ratedone MOD 48000 *)
  1105. BEGIN {EXCLUSIVE}
  1106. FOR j := 0 TO 31 DO
  1107. IF driver.recordchannels[j].active THEN
  1108. driver.recordchannels[j].rsilent := FALSE;
  1109. i := from;
  1110. WHILE (i <= to) & (driver.recordchannels[j].active) DO
  1111. IF driver.recordchannels[j].pos >= driver.recordchannels[j].first.content.len THEN
  1112. (* current buffer is over *)
  1113. driver.recordchannels[j].pos := 0;
  1114. (*driver.recordchannels[j].blistener(driver.recordchannels[j].first.content);*)
  1115. driver.AddBufferToReturn(driver.recordchannels[j].blistener,
  1116. driver.recordchannels[j].first.content);
  1117. driver.recordchannels[j].NextBuffer;
  1118. END;
  1119. driver.recordchannels[j].ratedone :=
  1120. driver.recordchannels[j].ratedone + driver.recordchannels[j].samplingRate;
  1121. nr := driver.recordchannels[j].ratedone MOD 48000;
  1122. IF nr # driver.recordchannels[j].ratedone THEN (* time to read out next sample *)
  1123. driver.recordchannels[j].ratedone := nr;
  1124. IF ~driver.recordchannels[j].rsilent THEN
  1125. driver.rallsilent := FALSE;
  1126. sample[0] := driver.pr2[i];
  1127. sample[1] := driver.pr2[i+1];
  1128. sample[2] := driver.pr2[i+2];
  1129. sample[3] := driver.pr2[i+3];
  1130. FOR l := 0 TO 1 DO
  1131. signed := SYSTEM.VAL(INTEGER, sample[2*l]);
  1132. lsigned := LONG(signed);
  1133. lsigned := lsigned*(driver.recordchannels[j].vol) DIV 256;
  1134. Clip(lsigned);
  1135. signed := SHORT(lsigned);
  1136. sample[2*l] := CHR(signed MOD 256);
  1137. sample[2*l+1] := CHR(signed DIV 256)
  1138. END;
  1139. (* convert recorded 16 bit stereo sample to target format *)
  1140. IF driver.recordchannels[j].samplingResolution=8 THEN
  1141. IF driver.recordchannels[j].nofSubChannels=1 THEN
  1142. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos]
  1143. := CHR( (ORD(sample[1])-128 + ORD(sample[3])-128) DIV 2)
  1144. ELSE
  1145. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos]
  1146. := CHR(ORD(sample[1])-128);
  1147. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos+1]
  1148. := CHR(ORD(sample[3])-128)
  1149. END
  1150. ELSE
  1151. IF driver.recordchannels[j].nofSubChannels=1 THEN
  1152. lsigned := SYSTEM.VAL(INTEGER, sample[0]);
  1153. lsigned := lsigned+SYSTEM.VAL(INTEGER, sample[2]);
  1154. signed := SHORT(lsigned DIV 2);
  1155. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos]
  1156. := CHR(signed MOD 256);
  1157. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos+1]
  1158. := CHR(signed DIV 256)
  1159. ELSE
  1160. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos]
  1161. := sample[0];
  1162. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos+1]
  1163. := sample[1];
  1164. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos+2]
  1165. := sample[2];
  1166. driver.recordchannels[j].first.content.data[driver.recordchannels[j].pos+3]
  1167. := sample[3]
  1168. END
  1169. END
  1170. END;
  1171. driver.recordchannels[j].pos:= driver.recordchannels[j].pos+driver.recordchannels[j].delta
  1172. END;
  1173. INC(i, 4)
  1174. END (*WHILE*)
  1175. END
  1176. END;
  1177. IF ~driver.rallsilent THEN (* make sure recording is in progress *)
  1178. IF ~ (4 IN SYSTEM.VAL(SET, driver.EsState.rctrl)) THEN
  1179. Machine.Portout8(driver.base+Es1370RegMemPage, 0DX); (*1101*)
  1180. Machine.Portout32(driver.base+34H, SYSTEM.VAL(LONGINT, Bsize DIV 4-1));
  1181. (*resets the counter of transferred longwords to 0*)
  1182. driver.EsState.rctrl := SYSTEM.VAL(LONGINT, {4}+SYSTEM.VAL(SET, driver.EsState.rctrl));
  1183. Machine.Portout32(driver.base+Es1370RegControl, driver.EsState.rctrl) (*AdcEn*)
  1184. END
  1185. ELSE (* make sure recording is stopped *)
  1186. IF (4 IN SYSTEM.VAL(SET, driver.EsState.rctrl)) THEN
  1187. driver.EsState.rctrl := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, driver.EsState.rctrl)-{4});
  1188. Machine.Portout32(driver.base+Es1370RegControl, driver.EsState.rctrl); (*AdcDis*)
  1189. FOR i := 0 TO Bsize-1 DO driver.pr2[i] := CHR(0) END
  1190. END
  1191. END
  1192. END Reccopy;
  1193. BEGIN
  1194. driver.allsilent := TRUE; first := TRUE;
  1195. driver.rallsilent := TRUE;
  1196. IF driver.reccopy=TRUE THEN
  1197. IF driver.rloopcount MOD 2 = 0 THEN
  1198. Reccopy(0, Bsize DIV 2 -1)
  1199. ELSE
  1200. Reccopy(Bsize DIV 2, Bsize -1)
  1201. END;
  1202. driver.reccopy := FALSE
  1203. END;
  1204. IF driver.playcopy = TRUE THEN
  1205. Setplaycopy(FALSE);
  1206. IF driver.loopcount MOD 2 = 0 THEN
  1207. Playcopy(0, Bsize DIV 2 -1)
  1208. ELSE
  1209. Playcopy(Bsize DIV 2, Bsize -1)
  1210. END
  1211. END
  1212. END Copy;
  1213. BEGIN {ACTIVE}
  1214. driver.playcopy := FALSE;
  1215. driver.reccopy := FALSE;
  1216. REPEAT (* wait for user/interrupt setting playcopy/reccopy as long as driver is loaded *)
  1217. Wait;
  1218. Copy
  1219. UNTIL 1=2
  1220. END Introbj;
  1221. VAR installedDrivers: Driver;
  1222. installed: LONGINT;
  1223. PROCEDURE DefaultBufferListener(buffer: SoundDevices.Buffer);
  1224. END DefaultBufferListener;
  1225. (** Called when unloading the module *)
  1226. PROCEDURE Cleanup;
  1227. BEGIN
  1228. WHILE installedDrivers # NIL DO
  1229. installedDrivers.Finalize;
  1230. installedDrivers := installedDrivers.next
  1231. END;
  1232. installed := 0;
  1233. END Cleanup;
  1234. PROCEDURE ScanPCI(vendor, device: LONGINT; name: Plugins.Name);
  1235. VAR index, bus, dev, fct, res, base, irq, i : LONGINT;
  1236. driver : Driver;
  1237. drivername : Plugins.Name;
  1238. BEGIN
  1239. driver := NIL;
  1240. index := 0;
  1241. WHILE (PCI.FindPCIDevice(device, vendor, index, bus, dev, fct) = PCI.Done) & (installed < 10) DO
  1242. IF Trace THEN
  1243. KernelLog.String("Bus "); KernelLog.Int(bus, 1);
  1244. KernelLog.String(", device: "); KernelLog.Int(dev, 1);
  1245. KernelLog.String(", function: "); KernelLog.Int(fct, 1);
  1246. KernelLog.String(", vendor/device "); KernelLog.Hex(ASH(vendor, 16) + device, 0); KernelLog.Ln;
  1247. END;
  1248. (* Get physical base address *)
  1249. res := PCI.ReadConfigDword(bus, dev, fct, PCI.Adr0Reg, base);
  1250. ASSERT(res=PCI.Done);
  1251. ASSERT(ODD(base));
  1252. DEC(base, base MOD 4); (* zero last 2 bits *)
  1253. IF Trace THEN KernelLog.String("Base address: "); KernelLog.Hex(base, 0); KernelLog.Ln END;
  1254. (* Get IRQ number *)
  1255. res := PCI.ReadConfigByte(bus, dev, fct, PCI.IntlReg, irq);
  1256. ASSERT(res=PCI.Done);
  1257. IF Trace THEN KernelLog.String("IRQ"); KernelLog.Int(irq, 1); KernelLog.Ln END;
  1258. (* Instanciate new driver object *)
  1259. NEW(driver, irq, base);
  1260. KernelLog.String("Ensoniq sound driver installed."); KernelLog.Ln;
  1261. i := 0;
  1262. WHILE name[i] # 0X DO drivername[i] := name[i]; INC(i) END;
  1263. drivername[i] := "#";
  1264. drivername[i + 1] := CHR(ORD("0") + installed);
  1265. drivername[i + 2] := 0X;
  1266. driver.SetName(drivername);
  1267. SoundDevices.devices.Add(driver, res); (* add NEW driver to installedDrivers *)
  1268. ASSERT(res=0);
  1269. INC(index)
  1270. END
  1271. END ScanPCI;
  1272. (** command forcing Init and the installation of a driver. *)
  1273. PROCEDURE Install*;
  1274. (* Init routine is called implicitly *)
  1275. END Install;
  1276. (* Initialize the driver module *)
  1277. PROCEDURE Init;
  1278. BEGIN
  1279. IF installedDrivers = NIL THEN
  1280. ScanPCI(1274H, 1371H, "ES1371");
  1281. ScanPCI(1274H, 1373H, "ES1373");
  1282. ScanPCI(1274H, 5880H, "5880 AudioPCI")
  1283. END;
  1284. END Init;
  1285. BEGIN {EXCLUSIVE}
  1286. Modules.InstallTermHandler(Cleanup);
  1287. installedDrivers := NIL;
  1288. installed := 0;
  1289. Init;
  1290. END EnsoniqSound.
  1291. EnsoniqSound.Install ~
  1292. SystemTools.Free EnsoniqSound ~
  1293. Installation
  1294. Add EnsoniqSound.Install to Configuration.XML, section 'Autostart' to load driver at system startup.