[comp.sys.mac.programmer] Reading data directly from MacRecorder

johnson@csli.STANFORD.EDU (Mark Johnson) (11/22/88)

Does anyone know how to read data directly from the MacRecorder into
a program?  LSC sources would be great!

Thanks in advance,

Mark Johnson

phil@mva.cs.liv.ac.uk (11/23/88)

In article <6522@csli.STANFORD.EDU>, johnson@csli.STANFORD.EDU (Mark Johnson) writes:
> 
> Does anyone know how to read data directly from the MacRecorder into
> a program?  LSC sources would be great!
> 
> Thanks in advance,
> 
> Mark Johnson
I second that request - but my language of preference is Pascal.  One of
the lecturers here is learning German, and thought up a project involving
the display of the desired sound and a comparison on screen with the
subject's own attempt at making that sound (it may prove easier to get the
sound right with a visual comparison).  Anyway, I have MacRecorder, so all I
need now are primitives to get some sound data from it.  Any help would be much
appreciated! 

Phil Jimmieson,           ***************************************************
Computer Science Dept.,   *        ** Note New Address & UserName **        *
Liverpool University,     * JANET : PHIL@UK.AC.LIV.CS.MVA                   *
Merseyside, England,      * ARPA  : PHIL%mva.cs.liv.ac.uk@cunyvm.cuny.edu   *
L69  3BX                  *                                                 *
                          * old address SQPHIL@UK.AC.LIV.CSVAX may work     *
(UK) 051-794-3689         ***************************************************

mystone@caen.engin.umich.edu (Dean Yu) (11/26/88)

In article <5411@mva.cs.liv.ac.uk>, phil@mva.cs.liv.ac.uk writes:
> In article <6522@csli.STANFORD.EDU>, johnson@csli.STANFORD.EDU (Mark Johnson) writes:
> > 
> > Does anyone know how to read data directly from the MacRecorder into
> > a program?  LSC sources would be great!
> I second that request - but my language of preference is Pascal.  One of
[...]
> sound right with a visual comparison).  Anyway, I have MacRecorder, so all I
> need now are primitives to get some sound data from it.  Any help would be much
> appreciated! 
> 

  Me three!  Me three!  (Can anyone from Farallon see this?)

______________________________________________________________________________
Dean Yu                            |  E-mail:    mystone@caen.engin.umich.edu
University of Michigan             |  Real-mail: Dean Yu
Computer Aided Engineering Network |             2413 Kelsey House
===================================|             600 E Madison
"These are MY opinions." (My       |             Ann Arbor, MI 48109
 employer doesn't want them.       |==========================================
 Actually, they don't really care  | 
 what I think.  But President      |   This space intentionally left blank.  
 Duderstadt does...)               | 
------------------------------------------------------------------------------  

mwilkins@jarthur.Claremont.EDU (Mark Wilkins) (11/29/88)

In article <5411@mva.cs.liv.ac.uk> phil@mva.cs.liv.ac.uk writes:
>In article <6522@csli.STANFORD.EDU>, johnson@csli.STANFORD.EDU (Mark Johnson) writes:
>> 
>> Does anyone know how to read data directly from the MacRecorder into
>> a program?  LSC sources would be great!

    I called Farallon about this.  The answer they gave me was that all one
had to do was raise the DTR line (I think) high.  The MacRecorder draws
power from this.  Then, the data, sampled at 22,000 Hz, comes in the serial
port.  Slower sampling rates are implemented in software, by throwing out
extra data.
    Hope this is enough to help you.

                        -- Mark Wilkins
		

jmunkki@kampi.hut.fi (Juri Munkki) (11/29/88)

In <3fe2023d.1285f@maize.engin.umich.edu> mystone@caen.engin.umich.edu Dean Yu:
>In article <5411@mva.cs.liv.ac.uk>, phil@mva.cs.liv.ac.uk writes:
>>In <6522@csli.STANFORD.EDU>, johnson@csli.STANFORD.EDU (Mark Johnson) writes:
>>> Does anyone know how to read data directly from the MacRecorder into
>>> a program?  LSC sources would be great!
>> I second that request - but my language of preference is Pascal.  One of
...
>>sound right with a visual comparison).  Anyway, I have MacRecorder, so all I
>>need now are primitives to get some sound data from it. Any help would be much
>>appreciated! 
>  Me three!  Me three!  (Can anyone from Farallon see this?)

I'm sorry to disappoint you guys, but all I have is MDS assembler source for
a program that reads from the MacNifty sound digitizer...

MacRecorder is somewhat more advanced that MacNifty/Impulse, but it is
compatible. You should be able to use this program for your purposes.

I don't think that it is possible/easy to use a high level language to
read the digitizer. Could one of you write a decent package to use the
digitizer. A code resource with an interface similar to a PACK would be
great. You could then use it with any language. I don't have the time to
do something like that right now. Please keep the code compatible with
all the different flavors of digitizers...

I hope the code works. I don't know where I got it, I have never tried to
compile it and I have planned to use it to write a similar, but more
advanced program in LS-C inline asm.

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

Since I couldn't find a copyright notice, source code follows:

; mod 12 30 85 tsh - fix for new digitizer
; written 5 27 85 Tom Hedges, Fractal Software

;	Example Oscilloscope Program

	XDEF	Start
	
; Bring in all the dirty constants
	INCLUDE	SysEquX.D

; Dirty System Constants
myRow	EQU	45			;row we start on screen
MotorOff EQU	$0DFF1FF		;Motor Off Control Base
trigC	EQU	350			;trigger count max


; Data
transTab DS.B	256			;translate table
oldVal	DS.W	512			;old screen bit


;Initialize All Managers
Start:	PEA	-4(A5)
	DC.W	$A86E	;_InitGraf
	DC.W	$A8FE	;_InitFonts
	DC.W	$A912	;_InitWindows
	DC.W	$A930	;_InitMenus
	CLR.L	-(SP)
	DC.W	$A97B	;_InitDialogs

; Setup Translate Table with bit-reversed indices
	LEA	transTab(A5),A0		;address translate table
	MOVEQ	#0,D4			;index
	MOVE.W	#255,D3			;outer loop count (256 entries)
sutrlp:	MOVEQ	#7,D2			;inner loop counter (8 bits in byte)
	MOVE.W	D4,D0			;get copy of index
brlp:	LSL.W	#1,D1			;shift index left one
	BTST.L	#0,D0			;test low bit of index
	BEQ.S	bitns			;not set
	ADDQ.W	#1,D1			;put bit into result
bitns:	LSR.W	#1,D0			;shift index right one
	DBF	D2,brlp
	MOVE.B	D1,(A0)+		;store new index
	ADDQ.W	#1,D4			;bump index
	DBF	D3,sutrlp

; Init oldVal Array to Zeroes
	LEA	oldVal(A5),A0
	MOVE.W	#511,D0
initOV	CLR.W	(A0)+
	DBF	D0,initOV

; Setup Scc
	MOVEM.L	SccRd,A0-A1		;get the base addresses for Scc
	MOVEQ	#2,D0			;fudge for Port A
	ADDA.W	D0,A0			;Scc Read Addr
	ADDA.W	D0,A1			;Scc Write Addr
; disable interrupts
	MOVE	SR,-(SP)		;setup for RTE
	ORI	#$300,SR		;Disable Interrupts
; WR 9
	MOVE.B	(A0),D0			;assure WR0 next
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#9,(A1)			;WR 9
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$02,(A1)		;NV only
; WR 4
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#4,(A1)			;WR 4
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$0C,(A1)		;2 stop bits, Asynch Mode
; WR 1
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#1,(A1)			;WR 1
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$01,(A1)		;No Rx/Tx Int, Ext Int ON (Mouse)
; WR 3
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#3,(A1)			;WR 3
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$C1,(A1)		;8 bits per Byte, Rx Enable
; WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#5,(A1)			;WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$7A,(A1)		;8 bits/char, send break, Tx enable
; WR 11
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#11,(A1)		;WR 11
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$30,(A1)		;TRxC-Bar is Rcv Clock (External)
					;BR Generator is Xmt Clock
; WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#14,(A1)		;WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$01,(A1)		;BR Enable, no weird modes
; WR 15
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#15,(A1)		;WR 15
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$08,(A1)		;Interrupt on CD Changes (Mouse)
; WR 0
	MOVE.L	(SP),(SP)
	MOVE.B	#$40,(A1)		;Reset Rx CRC to WR 0
	MOVE.L	(SP),(SP)
	MOVE.B	#$40,(A1)		;Reset Rx CRC to WR 0
; WR 9
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#9,(A1)			;WR 9
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$0A,(A1)		;MIE and NV

; turn off the motor
	LEA	MotorOff,A2		;address the motor off base
	TST.B	(A2)			;do a fetch

; init the sound output buffer to FF's for smallest clip
	MOVE.L	SoundBase,A2		;init the sound buffer addr
	MOVE.W	#SndBufWLen-1,D2	;size of sound buffer
@1	MOVE.B	#$FF,(A2)		;set to 255
	ADDQ.L	#2,A2			;skip two bytes
	DBF	D2,@1

; wait for clock from box to start
	MOVE.B	(A0),D0			;assure WR 0 next
	MOVEQ	#10,D1			;flush first 10 samples
	MOVE.L	(SP),(SP)		;(delay)
; loop until at least one character is there
@2	BTST.B	#0,(A0)			;test RR 0 for data available
	BEQ.S	@2			;inner loop until a char is there
	MOVE.B	4(A0),D0		;receive the character
	MOVEM.L	D0-D7,-(SP)		;kill time
	MOVEM.L	(SP)+,D0-D7
	DBF	D1,@2			;outer loop on characters read
	
; set Screen to Black
	MOVEA.L	ScrnBase,A2		; SCREEN ADDRESS
	MOVE.W	ScreenRow,D0		;get byte width of screen
	LSR.W	#2,D0			;divided by 4
	MULU	#MaxY,D0
	SUBQ.W	#1,D0			;loop count
@3	MOVE.L	#$FFFFFFFF,(A2)+	;set to ones 4 bytes
	DBF	D0,@3

; compute the place on screen to draw
	MOVE.W	#myRow,D0		; LOAD TOP SCAN OF SCOPE
	MULU	ScreenRow,D0		; times row length (clean)
	MOVEA.L	ScrnBase,A3		; SCREEN ADDRESS
	ADDA.W	D0,A3			; ADD ON OFFSET OF SCAN...

; now draw white lines above and below 'scope region
	MOVEA.L	A3,A2
	SUBA.W	ScreenRow,A2
	MOVE.W	ScreenRow,D0
	LSR.W	#2,D0
	SUBQ.W	#1,D0			;loop count
@4	CLR.L	(A2)+
	DBF	D0,@4
	MOVE.W	#257,D0
	MULU	ScreenRow,D0		; times row length (clean)
	MOVEA.L	A3,A2
	ADDA.W	D0,A2	
	MOVE.W	ScreenRow,D0
	LSR.W	#2,D0
	SUBQ.W	#1,D0			;loop count
@5	CLR.L	(A2)+
	DBF	D0,@5
	
; turn on the sound
	MOVE.L	VIA,A2			;get VIA device address
	BCLR	#VSndEnb,(A2)		;clear the sound disable bit

; receive characters and stuff them into the sound buffer
	MOVE.W	#-trigC,D3		;trigger count
	MOVEQ	#(512/8)-1,D6		;buffer byte count - 1
	MOVEQ	#7,D7			;complement bit
	LEA	transTab(A5),A4		;load translate table
	LEA	oldVal(A5),A6		;get start of old array

; 'outer' loop resets the sound buffer
riloop:	MOVE.L	SoundBase,A2		;init the sound buffer addr
	MOVE.W	#sndBufWLen-1,D4	;words in sound buffer - 1 for DBF

; D3 = 0: if scoping, <0: if waiting for TB clr, >0: if waiting for TB set
; D4 = sound buffer down ctr,
; D6 = buffer byte count - 1, D7 = bit in byte (complement)
; A0 = constant Scc Read Addr, A1 = constant Scc Write Addr,
; A2 = ptr into sound buffer, A3 = video byte ptr,
; A4 = constant transTab ptr, A5 = data region ptr,
; A6 = current ptr to oldVal array
loop:	MOVEQ	#25,D0			;clock off timeout
wcloop:	BTST.B	#0,(A0)			;test RR 0 for data available
	BNE.S	gotdata			;data is there!
; no data yet, count down and loop
	DBF	D0,wcloop
; time out: the box must have been turned off
	BRA.S	doneOsc			;exit

; we have a character!!!!!
; assume top byte of D0.W is zeroes!!!!
gotdata	MOVE.B	4(A0),D0		;receive the character
	MOVE.B	0(A4,D0.W),D0		;get translated value
	MOVE.B	D0,(A2)			;put translated byte to sound buf
	ADDQ.L	#2,A2			;bump sound buffer ptr
	TST.W	D3			;test 'scope mode
	BEQ.S	@1			;normal mode

; waiting to trigger 'scope
	BPL.S	@2			;branch if waiting for < 0
; <0: waiting for top bit clear
	TST.B	D0			;test top bit
	BPL.S	@3			;branch if clear
	ADDQ.W	#1,D3			;count down
	BRA.S	doloop
@3	MOVE.W	#trigC,D3		;wait for top bit set
	BRA.S	doloop
; >0: waiting for top bit set
@2	TST.B	D0			;test sign of D0
	BMI.S	@4			;branch if set
	SUBQ.W	#1,D3			;count up
	BRA.S	doloop
@4	MOVEQ	#0,D3			;we've triggered

; output oscilloscope-like display to screen
@1	LSL.W	#6,D0			;shift into vertical byte offset
	MOVE.W	(A6),D1			;get old value
	MOVE.W	D0,(A6)+		;and replace with new one
	BSET	D7,0(A3,D1.W)		;clear the old bit
	BCLR	D7,0(A3,D0.W)		;set the current bit
	SUBQ.W	#1,D7			;decrement bit, N set if -1
	BPL.S	doloop			;no, loop quick

	MOVEQ	#7,D7			;set bit to 7
	ADDQ.L	#1,A3			;bump to next horizontal byte
	DBF	D6,doloop

; test for aborted by mouse button down
	MOVE.L	VIA,A3			;get VIA device address
	BTST	#vSW,(A3)
	BNE.S	@9			; no, reset video buffer and loop
; Aborted::: wait for mouse to rise upon the abort
@8	BTST	#vSW,(A3)
	BEQ.S	@8			; loop until mouse is up
	BRA.S	doneOsc

; reset video buffer
@9	MOVE.W	#-trigC,D3		;reset trigger count
	MOVEQ	#(512/8)-1,D6		;buffer byte count - 1
; compute the place on screen to draw
	MOVE.W	#myRow,D0		; LOAD TOP SCAN OF SCOPE
	MULU	ScreenRow,D0		; times row length (clean)
	MOVEA.L	ScrnBase,A3		; SCREEN ADDRESS
	ADDA.W	D0,A3			; ADD ON OFFSET OF SCAN...
	LEA	oldVal(A5),A6		;get start of old array


doloop:	DBF	D4,loop			;count and test for Sound Buf empty
	BRA	riloop			;Reset Sound Buffer and Loop

; done - clean things up
; turn internal clock on, enable BR generator, 
doneOsc: MOVE.B	(A0),D0			;assure WR0 next
; WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#5,(A1)			;WR 5
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$6A,(A1)		;8 bits/char, Tx enable
; WR 11	
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#11,(A1)		;WR 11
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$50,(A1)		;baudrate generator clocking
; WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#14,(A1)		;WR 14
	MOVE.L	(SP),(SP)		;(delay)
	MOVE.B	#$01,(A1)		;BR Enable, no weird modes

; turn off the sound
	MOVE.L	VIA,A2			;get VIA device address
	BSET	#VSndEnb,(A2)		;set the sound disable bit

; allow interrupts
	ANDI	#$CFF,SR

; return to shell
	DC.W	$A9F4	;_ExitToShell
	
	END
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

oster@dewey.soe.berkeley.edu (David Phillip Oster) (12/01/88)

Archived on sumex-2600.stanford.edu (and eventually on
sumex-aim.stanford.edu, when the archive moves to its permanent home.) is
a program that reads the MacNifty Audio Digitizer directly. After the
informative posting on the hardware of the Farallon digitizer, I believe
that it will read it also.

The program is called "scope.asm" and is probably in a .pit file of sound
tools. It reads audio data from the audio digitizer and displays it,
oscilliscope style, on the Mac screen.

Note: the program uses noops to keep from accessing the VIA too often, so
you'll need more noops to use it on a II.

It is in assembly language.