Difference between revisions of "CSC231 readWaveFile.asm"
(→wav.inc) |
(→readWavFile.asm) |
||
Line 19: | Line 19: | ||
;;; | ;;; | ||
;;; Example of use: | ;;; Example of use: | ||
− | ;;; nasm -f elf | + | ;;; |
− | ;;; ld -o | + | ;;; nasm -f elf readWavFile.asm |
+ | ;;; ld -o readWavFile readWavFile.o | ||
;;; rm goodbye2.wav | ;;; rm goodbye2.wav | ||
;;; aplay goodbye.wav | ;;; aplay goodbye.wav | ||
− | ;;; ./ | + | ;;; ./readWavFile |
;;; aplay goodbye2.wav | ;;; aplay goodbye2.wav | ||
;;; | ;;; |
Revision as of 11:16, 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 readWavFile.asm
;;; ld -o readWavFile readWavFile.o
;;; rm goodbye2.wav
;;; aplay goodbye.wav
;;; ./readWavFile
;;; 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