Difference between revisions of "CSC231 readWaveFile.asm"
(→readWavFile.asm) |
(→readWavFileSkel.asm) |
||
(8 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 23: | Line 106: | ||
;;; ld -o readWavFile readWavFile.o | ;;; ld -o readWavFile readWavFile.o | ||
;;; rm goodbye2.wav | ;;; rm goodbye2.wav | ||
− | ;;; aplay goodbye.wav | + | ;;; aplay goodbye.wav # will say "goodbye" |
;;; ./readWavFile | ;;; ./readWavFile | ||
− | ;;; aplay goodbye2.wav | + | ;;; aplay goodbye2.wav # will say "goodbye goodbye" |
;;; | ;;; | ||
Line 104: | Line 187: | ||
;;; 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 | ||
+ | ;;; | ||
+ | |||
Line 253: | 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 261: | 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