Difference between revisions of "CSC231 readWaveFile.asm"

From dftwiki3
Jump to: navigation, search
(Created page with '--~~~~ ---- =readWavFile.asm= <code><pre> ;;; readWaveFile.asm ;;; D. Thiebaut ;;; demo program ;;; reads a wav file, doubles up the sampled data, and ;;; writes the data to a …')
 
(wav.inc)
Line 98: Line 98:
  
 
<code><pre>
 
<code><pre>
;;; wav.inc
+
;;; wav.inc
 
;;; D. Thiebaut (c) 2010
 
;;; D. Thiebaut (c) 2010
 
;;; reads a wav file and stores it in a static memory
 
;;; reads a wav file and stores it in a static memory
 
;;; buffer.
 
;;; buffer.
 
;;;
 
;;;
;;;
+
;;;  
 +
 
  
 
;;;--- some system related constants   
 
;;;--- some system related constants   

Revision as of 11:13, 24 October 2010

--D. Thiebaut 15:11, 24 October 2010 (UTC)


readWavFile.asm

;;; readWaveFile.asm
;;; D. Thiebaut
;;; demo program
;;; reads a wav file, doubles up the sampled data, and
;;; writes the data to a new wav file.
;;;
;;; 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, so make sure
;;; your wave files are less than that size.
;;;
;;; Example of use:
;;;  nasm  -f elf readWavFiles.asm
;;;  ld -o readWavFiles readWavFiles.o
;;;  rm goodbye2.wav
;;;  aplay goodbye.wav
;;;  ./readWavFiles
;;;  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
	
	;; -----------------------------------------------------------
	;; code area
	;; -----------------------------------------------------------

	section	.text
	global	_start

_start:
	
;;; 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 the number of bytes of sound samples
	mov		ecx, [noBytesSamples]

;;; use esi to point to beginning of buffer, and edi to
;;; empty space passed end of samples in buffer
	
	mov		esi, [bufferAddress]	; esi points to start of buffer
	mov		ebx, [bufferAddress]
	add		ebx, [noBytesSamples]
	mov		edi, ebx        	; edi point to 1 past last
						; sample byte in  buffer

;;; copy sound at end of itself (repeat sound twice)
	
for:	mov		al, [esi]
	mov		[edi], al
	inc		esi
	inc		edi
	loop		for

	
;;; write contents of buffer to same new file
	
	mov		ebx, fileName2
	mov		ecx, [noBytesSamples]
	add		ecx, ecx
	writeSoundFile

;;; exit()

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


wav.inc

;;; wav.inc
;;; D. Thiebaut (c) 2010
;;; reads a wav file and stores it in a static memory
;;; buffer.
;;;
;;; 


;;;--- some system related constants  
%assign SYS_EXIT	1
%assign	SYS_WRITE	4
%assign SYS_READ	3
%assign SYS_LSEEK	19
%assign	SYS_STDOUT	1
%assign SYS_OPEN        5
%assign SYS_CLOSE	6
%assign SYS_CREATE	8

%assign O_RDONLY	000000q
%assign O_WRONLY        000001q	
%assign O_RDWR          000002q
%assign O_CREAT		000100q

%assign S_IRUSR		00400q
%assign S_IWUSR		00200q
%assign S_IXUSR		00100q


;;; ---------------------------------------------------------
;;; ____        _        
;;;|  _ \  __ _| |_ __ _ 
;;;| | | |/ _` | __/ _` |
;;;| |_| | (_| | || (_| |
;;;|____/ \__,_|\__\__,_|
;;;                      
;;; ---------------------------------------------------------
;; ----------------------------------------------------------
;; data segment
;; ----------------------------------------------------------

		section	.data
handle   	dd     	0		; the file handle for reading
noRead   	dd     	0		; and writing the sound file.
					; noRead is the # of bytes read
					; from file.

; definition of wav format taken from
; in https:ccrma.stanford.edu/courses/422/projects/WaveFormat/ 
	
        	section .bss
wavbuf		equ	$	        
chunkId       	resb	4		; contains string RIFF
chunkSiz 	resb	4	        ; size of rest of the file minus 8 bytes
format   	resb	4		; contains string WAVE
subchunk1Id 	resb  	4		; contains letters "fmt "
subchunk1Size 	resb	4		; 16 for PCM
audioformat 	resb	2
numchannels 	resb	2
samplerate  	resb	4
byterate    	resb 	4
blockalign  	resb	2
bitspersample 	resb	2
subchunk2Id 	resb	4
subchunk2Size 	resb 	4
HEADERSIZE 	equ   	$-wavbuf	
MAXBUF   	equ     100000
buffer   	resb    MAXBUF          ; 100,000 bytes of storage

;;; ---------------------------------------------------------
;;; __  __                          
;;;|  \/  | __ _  ___ _ __ ___  ___ 
;;;| |\/| |/ _` |/ __| '__/ _ \/ __|
;;;| |  | | (_| | (__| | | (_) \__ \
;;;|_|  |_|\__,_|\___|_|  \___/|___/
;;;
;;; ---------------------------------------------------------


;;; ---------------------------------------------------------
;;; --- MACRO -----------------------------------------------
;;;     print           msg,length
%macro  print           2               ; %1 = address %2 = # of chars
        pushad                          ; save all registers
        mov             edx,%2
        lea             ecx,[%1]
        mov             eax,SYS_WRITE
        mov             ebx,SYS_STDOUT
        int 0x80             
        popad                           ; restore all registers
%endmacro

;;; ---------------------------------------------------------
;;; --- MACRO -----------------------------------------------
;;;     print2        "quoted string"
%macro  print2        1               ; %1 = immediate string,
        section .data
%%str   db              %1
%%strL  equ             $-%%str
        section .text
        print           %%str, %%strL
%endmacro

;;; ---------------------------------------------------------
;;; --- MACRO -----------------------------------------------
;;; on entry:
;;;           ebx contains address of fileName (0 terminated)
;;; on exit:
;;;           eax:  no bytes of samples
;;;           ebx:  address of sample-data buffer 
;;;
%macro  readSoundFile   0 
	; open the file first
    	call   	        openFile        
	mov		[handle], eax

	; read it in the buffer
	mov	        ebx, [handle]
	mov		ecx, wavbuf
	mov		edx, MAXBUF+HEADERSIZE
	call         	readFile        
	mov		[noRead], eax

	; close it
	mov		ebx, [handle]
	call		close

	; return parameters
	mov		eax, [noRead]
	sub		eax, 44			; # bytes of samples
	mov		ebx, buffer
%endmacro

;;; ---------------------------------------------------------
;;; --- MACRO -----------------------------------------------
;;; writeSoundFile :  writes the header and the data to file
;;; on entry: 
;;;            ebx contains address of Z-ascci file name
;;;	       ecx contains number of bytes of data-samples

%macro  writeSoundFile   0
	; first compute the subchunk2Size and chunkSiz quantities
	; that are part of the sound wave format
        mov		eax, ecx
	mov		[subchunk2Size], eax
	add		eax, 44-8
	mov		[chunkSiz], eax

	; create a new file
	push		ecx			; save # bytes of data
	call		createFile
	mov		[handle], eax

	; write the buffer to file
	pop		edx			; get the # of data bytes back
	mov		ecx, wavbuf		; start of buffer
	mov		ebx, [handle]		
	call		writeFile

	; close the file
	mov		ebx, [handle]
	call		close
%endmacro
    
;;; ---------------------------------------------------------
;;; _____         _   
;;;|_   _|____  _| |_ 
;;;  | |/ _ \ \/ / __|
;;;  | |  __/>  <| |_ 
;;;  |_|\___/_/\_\\__|
;;;                   
;;; ---------------------------------------------------------

	section		.text	
;;; ---------------------------------------------------------
;;; 	createFile: create a file
;;;                 on entry,  filename in ebx
;;;                 on exit, handle in eaxe
;;;                 stops the program if an error occurs
createFile:
	mov	eax,SYS_CREATE
	mov	ecx, S_IRUSR|S_IWUSR|S_IXUSR
	int 	0x80	

	test	eax,eax
	jns	.ok
	print2  "Could not open file"
	mov	eax,SYS_EXIT
	mov	ebx,0
	int 	0x80			; final system call

.ok:
	ret

	
	
;;; ---------------------------------------------------------
;;; 	openFile: Opens a file and return its handle
;;;               filename in ebx on entry
;;;               handle in eax on exit, if successful
;;;               stops program on errors

openFile:
	mov	eax,SYS_OPEN
	mov	ecx, O_RDWR
	mov	edx, S_IRUSR|S_IWUSR|S_IXUSR
	int 	0x80	

	test	eax,eax
	jns	.ok

	print2  "Could not open file"
	mov	eax,SYS_EXIT
	mov	ebx,0
	int 	0x80			; final system call
.ok:
	ret

;;; ---------------------------------------------------------	
;;; 	readFile: reads an open file in a buffer
;;;	on entry, ebx contains the handle
;;;               ecx contains the buffer address
;;;               edx contains the number of bytes to read
;;;     on exit, eax contains the number of bytes read

; handle, buffer, buffer-length, number-bytes-read
readFile:
	mov	eax,SYS_READ
	int 	0x80	
	ret	


	
;;; ---------------------------------------------------------	
;;; 	writeBuf: writes a buffer to file 
;;;               handle, buffer, noBytesToWrite
;;;     on entry, ebx contains the handle, 
;;;               ecx, the buffer address
;;;               edx the # of bytes to wrie
writeFile:
	mov	eax,SYS_WRITE
	int 	0x80		


	
;;; ---------------------------------------------------------	
;;;	close   closes the file
;;;     on entry, ebx contains the handle
close:
	mov	eax,SYS_CLOSE
	int 	0x80	
	ret