CSC231 Homework 6 Solution 2010

From dftwiki3
Revision as of 18:46, 21 November 2010 by Thiebaut (talk | contribs)
Jump to: navigation, search

--D. Thiebaut 14:58, 12 November 2010 (UTC)



 
;;; hw7Sol.asm
;;; D. Thiebaut
;;; Solution Program for HW #7
;;; reads a wav file, and adds an echo to it.  
;;; Algorithm:
;;;     first clear the whole buffer, to make it silent
;;;     read the sound file goodby2.wav, record N samples: abcdef...z
;;;     make a copy of all N samples at the end of the first N samples: abcde...zabcde...z
;;;     add shifted value of first N samples over second half, with an offset of 1500.  Shift is 1 bit
;;;     add shifted value of first N samples over second half, with an offset of 3000. Shift is 2 bits
;;;     copy N+3000 samples from second part of buffer to first part of buffer
;;;     write N+3000 samples to goodbye2.wav.
;;; The name of the wav file is hard-coded in the program: goodbye.wav
;;; The name of the output file is also hard-coded: goodbye2.wav
;;; 
;;; This program uses wav.inc for accessing the wav file.
;;; wav.inc contains a 100KB buffer to hold the wav file
;;;
;;;
;;; Example of use:
;;;  nasm  -f elf hw7sol.asm
;;;  ld -o hw7sol hw7sol.o
;;;  rm goodbye2.wav
;;;  aplay goodbye.wav
;;;  ./hw7sol
;;;  aplay goodbye2.wav
;;;
	
%include "wav.inc"
        
	;; -----------------------------------------------------------
	;; data segment
	;; -----------------------------------------------------------

		section	.data
fileName 	db      "goodbye.wav",0
fileName2 	db	"goodbye2.wav", 0
	
noBytesSamples  dd	0		; # of bytes of samples
bufferAddress	dd	0		; safe place to keep address of buffer
offset		dd	1500		; offset for echo
endBuffer	dd	0		; address of 1st empty byte after sound
					; samples
noShifts	db	1		; amount of shifting to do with
					; the echoed sound. Shifting by 1 means
					;  dividing by 2.
	
	;; -----------------------------------------------------------
	;; code area
	;; -----------------------------------------------------------

	section	.text
	global	_start

_start:

;;; clear the whole buffer.  This actually makes the whole 
;;; buffer contain silent sounds...

	mov		ecx, MAXBUF + (buffer-wavbuf)
	mov		ebx, buffer
.for:	mov		byte [ebx], 0
	loop		.for
	
;;; open the file and put its contents in Buffer.
;;; keep track of # of bytes read in noRead

	mov		ebx, fileName
	readSoundFile	
	mov		[noBytesSamples], eax
	mov		[bufferAddress], ebx

;;; compute address of free space at end of buffer
	
	mov		eax, [bufferAddress] ; compute beginning address of 
	add		eax, [noBytesSamples] ; space at end of sound
	mov		[endBuffer], eax     ; save it


;;; make a copy of the original sound at the end of itself in buffer
;;; make esi point to buffer
;;; make edi point to end of buffer so that we can copy original file in 

copy1:	mov		esi, [bufferAddress]
	mov		edi, [endBuffer]
	mov		ecx, [noBytesSamples]
.for:	mov		al, [esi]
	mov		[edi], al
	inc		esi
	inc		edi
	loop		.for

;;; add original sound over its copy, dividing intensity by 1/2
;;; and with an offset of 1500 (or whatever is in [offset])

	call		copyAdd

;;; add original sound over its copy, dividing intensity by 1/4
;;; and with an offset of 3000 (or whatever is in [offset])

	mov		eax, [offset]
	add		[offset], eax 		; double offset size
	inc		byte [noShifts]		; get ready to divide by 4
	call		copyAdd

;;; copyBack to original buffer
copyBack:
	mov		esi, [endBuffer]
	mov		edi, [bufferAddress]
	mov		ecx, [noBytesSamples]
	add		ecx, [offset]
	add		ecx, [offset]
.for:	mov		al, [esi]
	mov		[edi], al
	inc		esi
	inc		edi
	loop		.for
	
;;; same code, but this time divide
;;; write contents of buffer to same new file
	
	mov		ebx, fileName2
	mov		ecx, [noBytesSamples]
	add		ecx, [offset]
	add		ecx, [offset]
	writeSoundFile

;;; exit()

	mov	eax,SYS_EXIT
	mov	ebx,0
	int 	0x80			; final system call

;;; -------------------------------------------------------------
;;; copySound: copy from esi to edi a number of bytes the number
;;;            of which is in ecx.  Registers unmodified.
;;; -------------------------------------------------------------
copySound:
	pushad
.for:	mov		al,[esi]
	mov		[edi],al
	inc		esi
	inc		edi
	loop		.for
	popad
	ret

;;; -------------------------------------------------------------
;;; copyAdd: copies samples from beginning of buffer address
;;;          to end of buffer + offset.  Each original sample
;;;          is first shifted by the amount in [noShifts] before
;;;          addition.  Sound is clipped to 255 if result of
;;;          addition overflows.
;;; -------------------------------------------------------------
copyAdd:	
	mov		esi,[bufferAddress]
	mov		edi,[endBuffer]
	add		edi,[offset] 		; point 1 offset away in 2nd buffer
	mov		ecx,[noBytesSamples]

.for:	mov		al, [esi] 		; get original byte
	mov		ah, 0			; get ready to get shifted bit

	push		cx
	mov		cl, [noShifts]
	shr		al, cl			; decrease original sound according to what's
	pop		cx			; in cl
	
	add		al, [edi]
	adc		ah, 0			; put the carry of the previous operation
						; in ah
	neg		ah			; transform 0 in 00000000 or 1 in 11111111
	or		al, ah
	mov		[edi], al
	inc		esi
	inc		edi
	loop		.for

	ret