Problem Solving with Data Structures using Java: A Multimedia Approach Chapter 5: Arrays: A Static Data Structure for Sounds.

Slides:



Advertisements
Similar presentations
Georgia Institute of Technology Introduction to Processing Digital Sounds.
Advertisements

Introduction to Computer Science Theory
Garfield AP Computer Science
Chapter 4: Representation of data in computer systems: Sound OCR Computing for GCSE © Hodder Education 2011.
Sound, Part 3. Multiple Echoes Here is a recipe to create multiple echoes: def echoes(sndfile, delay, num): s1 = makeSound(sndfile) ends1 = getLength(s1)
Int 2 Multimedia Revision. Digitised Sound Analogue sound recorded from person, or real instruments.
Week 7 - Friday.  What did we talk about last time?  Array examples.
Quick Sort, Shell Sort, Counting Sort, Radix Sort AND Bucket Sort
Searching Kruse and Ryba Ch and 9.6. Problem: Search We are given a list of records. Each record has an associated key. Give efficient algorithm.
An Array-Based Implementation of the ADT List public class ListArrayBased implements ListInterface { private static final int MAX_LIST = 50; private Object.
Simple Sorting Algorithms
Quicksort. Quicksort I To sort a[left...right] : 1. if left < right: 1.1. Partition a[left...right] such that: all a[left...p-1] are less than a[p], and.
Quicksort.
1 CS 177 Week 15 Recitation Slides Review. Announcements Final Exam on Sat. May 8th  PHY 112 from 8-10 AM Complete your online review of your classes.
 2007 Pearson Education, Inc. All rights reserved C Arrays.
Week 8: Audio Processing 1.  Light and sound are both transmitted in waves 2.
Simple Sorting Algorithms. 2 Bubble sort Compare each element (except the last one) with its neighbor to the right If they are out of order, swap them.
Intro-Sound-part21 Introduction to Processing Digital Sounds part 2 Barb Ericson Georgia Institute of Technology Oct 2009.
Introduction to Interactive Media 10: Audio in Interactive Digital Media.
Chapter 14: Sorting and searching. Chapter Goals To study several sorting and searching algorithms To appreciate that algorithms for the same task can.
Week 7 - Wednesday.  What did we talk about last time?  Introduction to arrays  Lab 6.
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 7: Modifying Samples in a Range.
Computer Some basic concepts. Binary number Why binary? Look at a decimal number: 3511 Look at a binary number: 1011 counting decimal binary
Discrete Structures Lecture 11: Algorithms Miss, Yanyan,Ji United International College Thanks to Professor Michael Hvidsten.
Hash Functions and the HashMap Class A Brief Overview On Green Marble John W. Benning.
Basics of Digital Audio Outline  Introduction  Digitization of Sound  MIDI: Musical Instrument Digital Interface.
1 Time Analysis Analyzing an algorithm = estimating the resources it requires. Time How long will it take to execute? Impossible to find exact value Depends.
Sound and audio. Table of Content 1.Introduction 2.Properties of sound 3.Characteristics of digital sound 4.Calculate audio data size 5.Benefits of using.
COSC 1P02 Introduction to Computer Science 4.1 Cosc 1P02 Week 4 Lecture slides “Programs are meant to be read by humans and only incidentally for computers.
Structuring Music CS1316: Representing Structure and Behavior.
Chapter 2 Array Data Structure Winter Array The Array is the most commonly used Data Storage Structure. It’s built into most Programming languages.
C++ Programming: From Problem Analysis to Program Design, Second Edition Chapter 19: Searching and Sorting.
Introduction to SOUND.
More Meaningful Jargon Or, All You Need to Know to Speak Like a Geek Sound.
Chapter 7: Modifying Samples in a Range. Chapter Objectives.
Georgia Institute of Technology Introduction to Processing Digital Sounds part 1 Barb Ericson Georgia Institute of Technology Sept 2005.
Georgia Institute of Technology Processing Sound Ranges Barb Ericson Georgia Institute of Technology July 2005.
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 7: Modifying Samples in a Range.
Dynamic Array. An Array-Based Implementation - Summary Good things:  Fast, random access of elements  Very memory efficient, very little memory is required.
CPSC1301 Computer Science 1 Chapter 8 Introduction to Processing Digital Sounds part 3.
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 6: Modifying Sounds Using Loops.
 2007 Pearson Education, Inc. All rights reserved C Arrays.
Intro-Sound-part1 Introduction to Processing Digital Sounds part 1 Barb Ericson Georgia Institute of Technology Oct 2009.
Chapter 8: Modifying Samples in a Range. Chapter Objectives.
Interactive Multimedia Sound Mikael Fernström. Data sources Microphones and transducers –Sample acoustic reality Synthesis –Simulate reality (and beyond.
Searching and Sorting Searching: Sequential, Binary Sorting: Selection, Insertion, Shell.
Java Programming: From Problem Analysis to Program Design, 4e Chapter 14 Searching and Sorting.
Manipulating Sound CS1316: Representing Structure and Behavior.
Sounds in Jython 16 bit samples : -32,768 and 32,767 Sound object holds all samples file = pickAFile() sound = makeSound( file ) SoundSample objects store.
Session 18 The physics of sound and the manipulation of digital sounds.
COSC 1P02 Introduction to Computer Science 5.1 Cosc 1P02 Week 5 Lecture slides Psychiatrist to patient "You have nothing to worry about - anyone who can.
Intro-Sound-Mod10-part31 Introduction to Processing Digital Sounds part 3 while loop, tracing, for loop, parameters Barb Ericson Georgia Institute of Technology.
Section 1.7 Comparing Algorithms: Big-O Analysis.
Problem Solving with Data Structures using Java: A Multimedia Approach Chapter 9: Lists and Trees for Structuring Sounds.
1 compares each element of the array with the search key. works well for small arrays or for unsorted arrays works for any table slow can put more commonly.
An Array-Based Implementation of the ADT List
CS1316: Representing Structure and Behavior
Week 7 - Wednesday CS 121.
Pearson Prentice Hall Physical Science: Concepts in Action
Processing Sound Ranges part 3
Introduction to Processing Digital Sounds part 2
CS1316: Representing Structure and Behavior
Processing Sound Ranges part 1
How sound works: Acoustics, the physics of sound
Search,Sort,Recursion.
Quicksort.
Processing Sound Ranges
Processing Sound Ranges part 3
CS1315: Introduction to Media Computation
Quicksort.
Presentation transcript:

Problem Solving with Data Structures using Java: A Multimedia Approach Chapter 5: Arrays: A Static Data Structure for Sounds

Chapter Objectives

Representing sounds Sounds are vibrations in the air (increases and decreases in air pressure) changing very rapidly. We can hear between 20 vibrations to 20,000 vibrations per second. The pitch A above middle C is 440 vibrations per second (Hertz, Hz, CPS, Cycles Per Second) We record the air pressure (samples) at regular intervals (sampling rate) in order to digitize the sound. CD quality sound samples 44,100 times per second. Each sample is 16 bits, for a range of +/- 32,000 (roughly).

Contrasting WAV and MIDI WAV files are sampled (recorded) sound. So is MP3, but that’s compressed. MIDI is a format that represents music. Literally, it records instruments and when a note is started and ended.

Loading and playing sounds Welcome to DrJava. > Sound s = new Sound("D:/cs1316/MediaSources/thisisat est.wav") > s.play() //Hear it normal > s.increaseVolume(2.0); > s.play();

increaseVolume method /** * Increase the volume of a sound **/ public void increaseVolume(double factor){ SoundSample [] samples = this.getSamples(); SoundSample current = null; for (int i=0; i < samples.length; i++) { current = samples[i]; current.setValue((int) (factor * current.getValue())); }

Issues in increaseVolume SoundSample is the name of the class for samples. There’s something named Sample already in Java, so it would get confusing. getSamples(), getValue(), and setValue() work just the same as in Python.

Methods that return sounds > Sound s = new Sound("D:/cs1316/MediaSources/ thisisatest.wav") > s.play() > s.reverse() Sound number of samples: Why do you think we’re seeing this?

Reverse returns a Sound! /** * Method to reverse a sound. **/ public Sound reverse() { Sound target = new Sound(getLength()); int sampleValue; for (int srcIndex=0,trgIndex=getLength()-1; srcIndex < getLength(); srcIndex++,trgIndex--) { sampleValue = this.getSampleValueAt(srcIndex); target.setSampleValueAt(trgIndex,sampleValue); }; return target; }

Methods that cascade nicely in Sound public Sound reverse() public Sound append(Sound appendSound) public Sound mix(Sound mixIn, double ratio) public Sound scale(double factor)

Little sounds in MediaSources -h: Half second -q: Quarter second -1 or -2: 1 or 2 seconds -tenth: 1/10 second -twentieth: 1/20 second

Making sound effects > Sound s = new Sound(FileChooser.getMediaPath("gonga-2.wav")); > Sound s2 = new Sound(FileChooser.getMediaPath("gongb-2.wav")); > s.play(); // create the first sound > s2.play(); // create the second sound > s.reverse().play(); // Play first sound in reverse > s.append(s2).play(); // Play first then second sound > // Mix in the second sound, so you can hear part of each > s.mix(s2,0.25).play(); > // Mix in the second sound sped up > s.mix(s2.scale(0.5),0.25).play(); > s2.scale(0.5).play(); // Play the second sound sped up > s2.scale(2.0).play(); // Play the second sound slowed down > s.mix(s2.scale(2.0),0.25).play();

Making collages public class MySoundCollage { public static void main(String [] args){ FileChooser.setMediaPath("D:/cs1316/MediaSources/"); Sound snap = new Sound(FileChooser.getMediaPath("snap-tenth.wav")); Sound drum = new Sound(FileChooser.getMediaPath("drumroll-1.wav")); Sound clink = new Sound(FileChooser.getMediaPath("clink-tenth.wav")); Sound clap = new Sound(FileChooser.getMediaPath("clap-q.wav")); Sound drumRev = drum.reverse().scale(0.5); Sound soundA = snap.append(clink).append(clink).append(clap).append(d rumRev); Sound soundB = clink.append(clap).append(clap).append(drum).append(s nap).append(snap); Sound collage = soundA.append(soundB).append(soundB).append(soun dA).append(soundA).append(soundB); collage.play(); }

How append() works /** * Return this sound appended with the input sound appendSound sound to append to this **/ public Sound append(Sound appendSound) { Sound target = new Sound(getLength() + appendSound.getLength()); int sampleValue; // Copy this sound in for (int srcIndex=0,trgIndex=0; srcIndex < getLength(); srcIndex++,trgIndex++) { sampleValue = this.getSampleValueAt(srcIndex); target.setSampleValueAt(trgIndex,sampleValue); }

End of append() // Copy appendSound in to target for (int srcIndex=0,trgIndex=getLength(); srcIndex < appendSound.getLength(); srcIndex++,trgIndex++) { sampleValue = appendSound.getSampleValueAt(srcIndex); target.setSampleValueAt(trgIndex,sampleValue); } return target; }

Mixing two sounds together public Sound mix(Sound mixIn, double ratio) { Sound target = new Sound(getLength()); int sampleValue, mixValue,newValue; // Copy this sound in for (int srcIndex=0,trgIndex=0; srcIndex < getLength() && srcIndex < mixIn.getLength(); srcIndex++,trgIndex++) { sampleValue = this.getSampleValueAt(srcIndex); mixValue = mixIn.getSampleValueAt(srcIndex); newValue = (int)(ratio*mixValue) + (int)((1.0-ratio)*sampleValue); target.setSampleValueAt(trgIndex,newValue); } return target; } /** * Mix the input sound with this sound, with percent ratio of input. * Use mixIn sound up to length of this sound. * Return mixed sound. mixIn sound to mix in ratio how much of input mixIn to mix in **/ /** * Mix the input sound with this sound, with percent ratio of input. * Use mixIn sound up to length of this sound. * Return mixed sound. mixIn sound to mix in ratio how much of input mixIn to mix in **/

Scale() public Sound scale(double factor) { Sound target = new Sound((int)(factor *(1 + getLength()))); int sampleValue; // Copy this sound in for (double srcIndex=0.0,trgIndex=0; srcIndex < getLength(); srcIndex+=(1/factor),trgIndex++) { sampleValue = getSampleValueAt((int)srcIndex); target.setSampleValueAt((int) trgIndex,sampleValue); } return target; } /** * Scale up or down a sound by the given factor * (1.0 returns the same, 2.0 doubles the length, * and 0.5 halves the length) factor ratio to increase or decrease **/ /** * Scale up or down a sound by the given factor * (1.0 returns the same, 2.0 doubles the length, * and 0.5 halves the length) factor ratio to increase or decrease **/

How do we insert and delete sound? Welcome to DrJava. > Sound test = new Sound("D:/cs1316/MediaSources/thisisatest.wav"); > test.getLength() > Sound clink = new Sound("D:/cs1316/MediaSources/clink- tenth.wav"); > clink.getLength() 2184 > test.insertAfter(clink,40000) > test.play()

Handling the error cases > Sound test2 = new Sound("D:/cs1316/MediaSources/thisisat est.wav"); > test.insertAfter(test2,40000) > test.play()

First, making room start this.getLength() inSound.getLength() start start+inSound.getLength() 1294 …

Second, copying in inSound.getLength() start start+inSound.getLength() 1294 …

insertAfter method /** * Insert the input Sound after the specified start * Modifies the given sound inSound Sound to insert start index where to start inserting the new sound */ public void insertAfter(Sound inSound, int start) { SoundSample current=null; // Find how long inSound is int amtToCopy = inSound.getLength(); int endOfThis = this.getLength()-1;

if (start + amtToCopy - 1 > endOfThis) { // If too long, copy only as much as will fit amtToCopy = endOfThis-start+1; } else { // If short enough, need to clear out room. // Copy from endOfThis-amtToCopy+1;, moving backwards // (toward front of list) to start, // moving UP (toward back) to endOfThis // KEY INSIGHT: How much gets lost off the end of the // array? Same size as what we're inserting -- amtToCopy for (int source=endOfThis-amtToCopy; source >= start ; source--) { // current is the TARGET -- where we're copying to current = this.getSample(source+amtToCopy); current.setValue(this.getSampleValueAt(source)); } // NOW, copy in inSound up to amtToCopy for (int target=start,source=0; source < amtToCopy; target++, source++) { current = this.getSample(target); current.setValue(inSound.getSampleValueAt(source)); }

Setting up the variables SoundSample current=null; // Find how long insound is int amtToCopy = inSound.getLength(); int endOfThis = this.getLength()-1;

Checking for room if (start + amtToCopy - 1 > endOfThis) {// If too long, copy only as much as will fit amtToCopy = endOfThis-start+1;} else { // If short enough, need to clear out room.

Now, copy down else { // If short enough, need to clear out room. // Copy from endOfThis-amtToCopy;, moving backwards // (toward front of list) to start, // moving UP (toward back) to endOfThis // KEY INSIGHT: How much gets lost off the end of the // array? Same size as what we're inserting -- amtToCopy for (int source=endOfThis-amtToCopy; source >= start ; source--) { // current is the TARGET -- where we're copying to current = this.getSample(source+amtToCopy); current.setValue(this.getSampleValueAt(source)); }

Finally, copy in the new sound //** Second, copy in inSound up to amtToCopy for (int target=start,source=0; source < amtToCopy; target++, source++) { current = this.getSample(target); current.setValue( inSound.getSampleValueAt(source)); }

How do we delete? > Sound test = new Sound("D:/cs1316/MediaSources/thisisat est.wav"); > test.getLength() > test.delete(2000,30000) > test.play() // We hear “This test”

First, copy from end to getLength, back to start this.getLength()endstart This distance is start-end

Then, clear out the end this.getLength()endstart … This distance is start-end. And we’ll go from the length, backwards.

Deleting method /** * Delete from start to end in this sound start where to start deletion end where to stop deletion **/ public void delete(int start, int end){ int value = 0; // Basically, we simply copy from "end" to getLength back to start for (int source=end, target=start; source < this.getLength(); source++, target++) {value = this.getSampleValueAt(source); this.setSampleValueAt(target,value);} // Then clear out the rest. Gap is end-start+1 length int gap = end-start+1; for (int i=1; i <= gap ; i++) { this.setSampleValueAt(this.getLength()-i,0);} }

First, copy up—over the start to end gap // Basically, we simply copy from "end" to getLength back to start for (int source=end, target=start; source < this.getLength(); source++, target++) {value = this.getSampleValueAt(source); this.setSampleValueAt(target,value);}

Then, clear out the gap at the end // Then clear out the rest. Gap is end-start+1 length int gap = end-start+1; for (int i=1; i <= gap ; i++) { this.setSampleValueAt( this.getLength()-i, 0);}

Arrays: Strengths and weaknesses Strengths: Easy to understand Very efficient “Static”—it’s always the same length (shape?) Weaknesses: Any change in the middle is hard to do Expensive in complexity and processing “Static”—it’s always the same length (shape?)

Think about the timing How long does it take to insert or delete? Depends on the number of elements n We call that O(n): The speed of execution changes depending on n That’s linear time. We call O() “Big-O” That’s the upper bound of how long an algorithm will take. “Big-Omega” is the lower bound, the fastest possible execution. “Big-Theta” describes the upper bound = lower bound.

Other complexities of algorithms O(n) is linear time. O(1) is constant time. Execution time is same, no matter how much data. A good sorting algorithm is O(n log(n)). Simple sorting algorithms are O(n 2 ) There are slower algorithms. Optimization algorithms can be O(n!)