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 …')
 
(readWavFileSkel.asm)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
--[[User:Thiebaut|D. Thiebaut]] 15:11, 24 October 2010 (UTC)
 
--[[User:Thiebaut|D. Thiebaut]] 15:11, 24 October 2010 (UTC)
 
----
 
----
 +
__TOC__
 +
=readWavFileSkel.asm=
 +
 +
*This is a skeleton file for performing operations on a sound file.  The names of the input and output sound files are hard coded in the program as '''goodbye.wav''' and '''goodbye2.wav'''.
 +
 +
 +
<code><pre>
 +
;;; readWaveFileSkel.asm
 +
;;; D. Thiebaut
 +
;;; demo program
 +
;;; reads a wav file,  and writes the data to a new wav file without modification.
 +
;;;
 +
;;; 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 readWavFile.asm
 +
;;;  ld -o readWavFile readWavFile.o
 +
;;;  rm goodbye2.wav
 +
;;;  aplay goodbye.wav                  # will say "goodbye"
 +
;;;  ./readWavFile
 +
;;;  aplay goodbye2.wav                  # will say "goodbye goodbye"
 +
;;;
 +
 +
%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
 +
 +
 +
 +
 +
;;;  * * *  PUT YOUR CODE HERE! * * *
 +
 +
 +
 +
 +
;;; write contents of buffer under new file name
 +
 +
mov ebx, fileName2
 +
mov ecx, [noBytesSamples]
 +
writeSoundFile
 +
 +
;;; exit()
 +
 +
mov eax,SYS_EXIT
 +
mov ebx,0
 +
int 0x80 ; final system call
 +
 +
 +
</pre></code>
  
 
=readWavFile.asm=
 
=readWavFile.asm=
 +
 +
* This is an example based on the skeleton file that copies the sound twice, repeating it.
  
 
<code><pre>
 
<code><pre>
Line 19: Line 102:
 
;;;
 
;;;
 
;;; Example of use:
 
;;; Example of use:
;;;  nasm  -f elf readWavFiles.asm
+
;;;
;;;  ld -o readWavFiles readWavFiles.o
+
;;;  nasm  -f elf readWavFile.asm
 +
;;;  ld -o readWavFile readWavFile.o
 
;;;  rm goodbye2.wav
 
;;;  rm goodbye2.wav
;;;  aplay goodbye.wav
+
;;;  aplay goodbye.wav                   # will say "goodbye"
;;;  ./readWavFiles
+
;;;  ./readWavFile
;;;  aplay goodbye2.wav
+
;;;  aplay goodbye2.wav                 # will say "goodbye goodbye"
 
;;;
 
;;;
 
 
Line 98: Line 182:
  
 
<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.
 
;;;
 
;;;
 +
;;; Good reference: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
 
;;;
 
;;;
 +
;;; Typical use:
 +
;;;
 +
;;;          ; to read a sound file
 +
;;;
 +
;;;                    section  .data
 +
;;;          fileName          db      "goodbye.wav", 0
 +
;;;        fileName2       db  "goodbye2.wav", 0
 +
;;;        noBytesSamples  dd  0
 +
;;;          bufferAddress  dd  0
 +
;;;
 +
;;;              section .text
 +
;;; 
 +
;;;                          mov      ebx, fileName    ; ebx points to fileName
 +
;;;                            readSoundFile              ; reads file and stores it in mem
 +
;;;                            mov      [noBytesSamples], eax
 +
;;;                      mov      [bufferAddress], ebx
 +
;;;
 +
;;;          ; to write a sound file
 +
;;;                   
 +
;;;                            mov    ecx,[noBytesSamples] ; the # of bytes of data to write
 +
;;;                                                          ; (does not include header)
 +
;;;                            mov      ebx, fileName 
 +
;;;                          writeSoundFile
 +
;;;
 +
 +
  
 
;;;--- some system related constants   
 
;;;--- some system related constants   
Line 251: Line 362:
 
; write the buffer to file
 
; write the buffer to file
 
pop edx ; get the # of data bytes back
 
pop edx ; get the # of data bytes back
 +
add edx, 44 ; for the header
 
mov ecx, wavbuf ; start of buffer
 
mov ecx, wavbuf ; start of buffer
 
mov ebx, [handle]
 
mov ebx, [handle]
Line 259: Line 371:
 
call close
 
call close
 
%endmacro
 
%endmacro
 +
 
      
 
      
 
;;; ---------------------------------------------------------
 
;;; ---------------------------------------------------------

Latest revision as of 11:55, 25 October 2010

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


readWavFileSkel.asm

  • This is a skeleton file for performing operations on a sound file. The names of the input and output sound files are hard coded in the program as goodbye.wav and goodbye2.wav.


;;; readWaveFileSkel.asm
;;; D. Thiebaut
;;; demo program
;;; reads a wav file,  and writes the data to a new wav file without modification.
;;;
;;; 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 readWavFile.asm
;;;  ld -o readWavFile readWavFile.o
;;;  rm goodbye2.wav
;;;  aplay goodbye.wav                   # will say "goodbye"
;;;  ./readWavFile
;;;  aplay goodbye2.wav                  # will say "goodbye goodbye"
;;;
	
%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




;;;  * * *  PUT YOUR CODE HERE! * * * 
	



;;; write contents of buffer under new file name
	
	mov		ebx, fileName2
	mov		ecx, [noBytesSamples]
	writeSoundFile

;;; exit()

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


readWavFile.asm

  • This is an example based on the skeleton file that copies the sound twice, repeating it.
;;; 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 readWavFile.asm
;;;  ld -o readWavFile readWavFile.o
;;;  rm goodbye2.wav
;;;  aplay goodbye.wav                   # will say "goodbye"
;;;  ./readWavFile
;;;  aplay goodbye2.wav                  # will say "goodbye goodbye"
;;;
	
%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.
;;;
;;; Good reference: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
;;;
;;; Typical use:
;;;
;;;           ; to read a sound file
;;;
;;;                    section  .data
;;;           fileName          db       "goodbye.wav", 0
;;;   	      fileName2	      	 db   	 "goodbye2.wav", 0
;;;   	      noBytesSamples  	 dd   	 0
;;;           bufferAddress   	 dd   	 0
;;;
;;;  	      	       section	 .text
;;;   	
;;;                   	        mov      ebx, fileName     ; ebx points to fileName
;;;                             readSoundFile              ; reads file and stores it in mem
;;;                             mov      [noBytesSamples], eax
;;;      	                mov      [bufferAddress], ebx
;;;
;;;    	      ;	to write a sound file
;;;                    
;;;                             mov    	 ecx,[noBytesSamples] ; the # of bytes of data to write
;;;                                                           ; (does not include header)
;;;                             mov      ebx, fileName  
;;;                   	        writeSoundFile
;;;



;;;--- 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
	add		edx, 44			; for the header
	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