B9 Foley Effects Editor
From SoftwarePractice.org
Contents |
Requirements
Project Description
This project is to design and implement a foley and sound effects editor for movie soundtracks. The foley track is used to create the sounds made by the actors in the film. Traditionally, the foley sounds are created specifically for a particular scene by using various props to create sounds like shoes walking, doors slamming, and so on.
The sounds effects crew works a little differently to the foley crew. They are less concerned with intimate sounds made by an actor (such as footsteps and chairs creaking), and more with "big" sounds like explosions and machine noises. They make use of an extensive library of pre-recorded sounds, including some purchased from other companies. Some sound effects will also be recorded or electronically synthesized specifically for a particular film.
This project is to implement an editor that must be possible to record sounds and add them to a library of sound clips. Then, specific clips from the library can be added to a "PlayList." The PlayList is a list of episodes, where each espisode consists of the sound clip ID, the time at which it is to be played, its volume.
The program is able to store an arbitrary number of espisodes, each of which can be played back at any time. To play the PlayList, the program plays back each sound at the appropriate time.
Team Memebers
- David Lannan
- Trung Tran
Stakeholders
- Foley Artists
- Foley Editor
- Sound Effects Crew
- Actors
- Producer
- Director
- System Administrator
- Film Studio
Use Scenarios
Record Sound
Chewie likes to record multiple takes of his voice so George can choose the right sound for the emotion. Mike records 25 takes of this sound for George, although gets bored at the reptitiveness.
Upload Sound
Mike places recorded sounds requested by George, who is indecisive as to which sound he liks of Chewies voice, into a central online library.
Position Sound
George wants to hear Luke's lightsaber in the right hand speaker as it extends on the right hand side of the screen, and then swoosh to the left.
Play track at specific time
George wants to try the sound he likes of Chewies scream at specific points in the clip, when Chewie is screaming at Han.
Use Case
Record Sound
User Action System Responsibility
1. User press Record button
from the Libray interface
2. Prompts a frame
3. User press Record to
start
4. User start recording
sounds
4. User press Stop button
5. Sounds are saved to system
Load clip to FoleyPlayer
User Action System Responsibility
1. User select a clip from
the Library interface
2. User press Load button
from the Library interface
3. Loads selected clip to the FoleyPlayer
Load all clips to FoleyPlayer
User Action System Responsibility
1. Load all button is pressed
from the Library interface
2. All the clips are loaded to FoleyPlayer
Add clips to Libray
User Action System Responsibility
1. User press Add button from
the Library interface
2. Ask user to select a clip
3. User selects a clip
3. Prompts to ask the User to give a name for the selected clip
4. User enter a name and
press OK
5. Add the selected clip with the given name to Library
Delete clip
User Action System Responsibility
1. User select a clip
2. User press Delete button
3. The selected clip is deleted from the Library
Add starting time to Episodes
User Action System Responsibility
1. User selects sound to be
played
2. User sets time to be
played in seconds
3.System stores information for when
clip should be played
Play Episodes
User Action System Responsibility
1. User enters starting for
clips from the FoleyPlayer
interface
2. User presses to play
episodes
3. Playing back episodes at specific times
Stop
User Action System Responsibility 1. User presses stop in the 2. Stops playing back the foley FoleyPlayer interface
Tools and Assumptions
Java and BlueJ are the main applications to develop the project. Jave Media Framework is used to playback soundclips and video clips which are added to a Library.
Since only one movie clip can be added to the Foley Effects Editor, the Video user interface can only be handle for a movie at a time. However, the Foley Effects Editor can be use for multiple movie soundtracks.
CRC Modelling
CRC Cards
Responsibilities | Collaborations
VideoUI
Interface to show video | JMF and sound clips playing | FoleyPlayer
LibraryUI
Interface allows users to | FoleyUI manage clips in the Libary | Libray
RecordUI
Interface to let users | FoleyUI record a sound with a name
FoleyUI
Main interface allows users | Track to open LibaryUI, stop and | FoleyPlayer play sound IDs at theirs | SoundClip starting time. Users can use | Library recoring button to record a | LibraryUI sound
Playlist
Contains sound events | SoundEvent
| FoleyPlayer
| VideoUI
| LibraryUI
Episode
Represent an episode | Jave Media Framework (JMF) of a clip to be play | at its starting time
JMF
Use Jav Media Framework | FoleyPlayer
to play clip ids | VideoUI
| SoundClip
| LibraryUI
Library
List of sound clip id's | SoundClip
Sound Clip / Temp Sound Clip
A sound clip location | Library - save clip id to library
FoleyPlayer
Init and show main GUI | Sound Clip
| Track
| JMF
| Library
Initial Class Diagram
Class Specifications
The attributes and method specifications are written in UML notation. Each method may have a pre/post conditions which specify the desired behaviour of each method. + is represented for a public attribute or a public method. And - is represented for privated method or arttribute.
Class Diagram
VideoUI
Purpose: To play back in sync with a movie video
class VideoUI extends JFrame Attributes: -visualComponent: Component Methods: +VideoUI() --Constructor +addVisual(Player: player) purpose: to display video pre: player<>null post: set the visualComponent to true
RecorderUI
Provide an interface that allow users to record sound and save it to a selected locations
class RecorderUI extends JFrame implements Runnable, ActionListener
Attributes:
-recordButton, stopButton: JButton
-filenameLabel: JLabel
-fileOut: File
-fileType: AudioFileFormat
-format: AudioFormat
-mike: TargetDataLine
-thread: Thread
Methods:
+RecorderUI()
--Constructor
pre:
post:filenameLabel, recordButton and stopButton are created and shown
+getNewFile()
purpose: create a new file for the recording sound to be saved
pre:
post: let soundFileName = getSoundFile()
then file = File(soundFileName)
return file
+startRecording()
purpose: recording a sound in a corrected format
pre:
post: try
mike = getLine AudioSystem
then open mike to getBufferSize
catch
if error then set the recordButton to false
set the foreground filenameLabel to red while recording a sound
+stopRecording()
purpose: stop recording a sound when the button is pressed
pre:
post: set the foreground filenameLabel to blue
stop the mike thread then close
+run()
pre:
post: start the mike thread
try
write(sound, fileType, fileOut) to the AudioSystem
catch
print try error
+getSoundFile()
purpose: ask users for a directory location of a recording sound to be saved
pre:
post: open a file diaglog to ask user where to save the recording sound
then return the name + pathname of the recording sound
+actionPerformed (event ActionEvent)
purpose: manages the action events from the recorderUI
pre:
post: if event = start_record then
startRecording() is called
else if event = stop_record then
stopRecording() is called
FoleyUI
This is the main interface where users can open a Library interface to add, load or delete clips. It also allows the user to manage control the playlist of a foley composition.
class FoleyUI extends Frame ActionListener
Attributes:
-libraryUIButton, exitButton, playButton, stopButton, recordButton: Button
-control: Component
-lblClipNameList, lblClipTimeList, lblClipControlComponent: Label
-clipNameList, clipTimeList: List
-recorderUI: RecorderUI
-playlist: PlayList
-libraryUI: LibraryUI
Methods:
+FoleyUI(foleyPlayer: FoleyPlayer)
--Constructor
pre: foleyPlayer <> null
post: self.foleyPlayer = foleyPlayer
libraryUIButton, exitButton, playButton, stopButton, recordButton, clipNamList and clipTimeList are
created and shown
+actionPerformed(event ActionEvent)
purpose: manages the various action events from the foleyUI
pre:
post: if event = library UI then
set the visible of the libraryUI is true
else if event = play button then
let playList = creatPlayList in
foleyPlayer.start(playList)
controlComponentY= COMP_START_Y
else if event = stop button then
foleyPlayer.stop(playList)
controlComponentY = COMP_START_Y
else if even = record button then
create and shown the record user interface
else if even = exit button then
exit the System
-creatPlayList(): Playlist
purpose: create and returns a playlist object
pre:
post: let playList: Playlist in attribute playlist is created
for each element in clipNameList and clipTimeList
playlist.addEpisode(clipNameList.getItem(), clipTimeList.time)
return playList
+addToPlayList
purpose: to display the clip playlist and time in the FoleyUI interface
pre:
post: clipNameList.add()
clipTimeList.add()
+removeFromPlayList(String item)
purpose: to update the clipNameList in the FoleyUI interface when a clip is deleted
pre:
post: for each element in the clipNameList
if clipNameList.getItemCount() = item then
remove clipNamlist(i)
remove clipTimeList(i)
+addControlComponent(Player player)
purpose: to a component so users can ajust the volume
pre:
post: let comp = player.getControlPanelComponent()
if comp <> null then
add(comp)
LibraryUI
Provide an interface that allows users to manage clips to be use in the library
class LibraryUI extends JFrame implements ActionListener
Attributes:
-addButton, deleteButton, loadButton, loadAllButton: JButton
-library: Library
-clipNameList: List
-foleyUI: FoleyUI
Methods:
+LibraryUI (Library library, FoleyUI foleyUI)
--Constructor
pre:
post: this.library = library
this.foleyUI = foleyUI
addButton, deleteButton, loadButton, loadAllButton and clipNameList are created, initialized and shown
+actionPerformed (ActionEvent event)
purpose: manage the action events from the libraryUI interface
pre:
post: if event = addButton then
show a file diaglog to allow users to select a clip
let pathname = filedialog.getDirectory()
flag false
while flag
open a panel to ask users to enter a name for the selected clip
if there is a name then
flag true
else if event = deleteButton then
let name = clipNamList.getSelectedItem
selectedIndex = clipNamList.getSelectedIndex
if a clip is highlight then
remove the selectedIndex in the clipNamList
deleteClip(name) is called
removeFromPlayList(name) from the FoleyUI is called
else if event = loadButton then
let name = clipNameList.getSelectedItem
loadClip(name)is called
addToPlayList(name) from the FoleyUI is called
else if event = loadAllButton then
for every name in the clipNameList
loadClip (name) is called
addToPlayList (name) from the FoleyUI is called
-addClip(String pathname, String clipName)
Purpose: creates and adds a clip object to the Libray based on the file in pathname
pre:
post: addClip(pathname, clipName) from the Library is called
-deleteClip(String clipName)
Purpose: deletes the clip with name clipName from the Library
pre:
post: deleteClip(clipName) from the Library is called
-loadClip(String clipName)
Purpose: load the clip with name clipName to the FoleyPlayer
pre:
post: loadClip(clipName) from the Library is called
-getLibrary()
Purpose: to return the Library
pre:
post: return library
FoleyPlayer
It initialises and shows the FoleyUI GUI, and is responsible for playing back foley compositions
class FoleyPlayer implements Runnable
Attributes:
-library: Library
-foleyUI: FoleyUI
-player: Player
-playerThread: Thread
-playList: PlayList
Methods:
+FoleyPlayer()
--Constructor
pre:
post: A new Library object is created
A new FoleyUI object is created and made visible
A new VideoUI object is created
+run()
pre:
post: start(playList)
+startPlayer(PlayList pList)
pre:
post: if playerThread = null then
playerThread = Thread(this)
playList = pList
start the playerThread
+start(PlayList playList)
Purpose: call the player to play back clips
pre: playList<>null
post: for each episode in playList JMFstart(player) is called every time an episode needs to be played
and addControlComponent(player) from the FoleyUI is also called for each episode needed to play
+stop(PlayList playList)
pre: playList<>null
post: for each episode in playList JMFstop(player) is called to stop
+getLibrary()
pre:
post: return library
+main(String[] args)
pre:
post: FoleyUI is created as frame
Library
Contains a collection of movie soundtracks for the foley track composition
class Library
Attributes:
clips: ArrayList
Methods:
+Library()
--Constructor
pre:
post: the clips has been created as an array
+addClip(String pathName, String name)
Purpose: to add a new sound clip to the library
pre: pathName<>null
post: a new SoundClip(pathName, name) is added to the next free position of the array clip
+getClipNames(): String[]
Purpose: returns the names of the sound clips in the array list
pre:
post: let clipnames = String[clips.size]
for every single clip in the arraylist, an array containing of each sound clip in the
library returned.
+loadCLip(String clipName): Boolean
Purpose: load a selected clip with the input name to the foley track composition
pre: clipName<>null
post: for every clip in the arrarylist of clips
let clip:SoundClip = the clip in clips
pathname: String = getPathname() in the clip
if pathName equal to clipNam or clip.getName() equal to clipName
if clip.load() successfull, then return true
else return false
+loadAllClips(): Boolean
Purpose: load all clips in the library to the foley track composition
pre:
post: for every single clip
clip:SoundClip = (SoundClip)clips.get()
if clip.load() is fail, then return false
else return true
+deleteClip(String clipName)
Purpose: to delete a selected clip from the library
pre: clipName<>null
post: for every single clip in the arraylist of clips
let clip:SoundClip = (SoundClip)clips.get(i)
if the clip in the arrarylist of clips equal to clipName, then the clip is deleted
+getClipPlayer(String clipName: javax.media.Player
Purpose: return player of the clip with the name equal to clipName
pre: clipName<>null
post: for every single clip in the arraylist of clips
let clip:SoundClip = the clip in the arrarylist with name equal to clipName
return clip.getPlayer()
+getClips():ArrayList
Purpose: to the return the all clips in the arrarylist of clips
pre:
post: return clips
+getClip(int clipNumber): SoundClip
Purpose: returns the number of clip in the SoundClip of the clips array
pre: clipNumber < the size of the array clips
post: return the clipNumber in (SoundClip)clips
JMF
Java Media Framework is used to play back sound and movie files
class JMF
Attributes:
Methods:
+static load(File file): Player
Purpose: creates, returns and loads a Player to the specific sound file
pre:
post: let listener = ControllerAdapter of the ControllerListener
stop(event) method is created
player = Player of the event getSource()
player.setMediaTime
use file paramete to locate the media file and build a URL object to describe the file
creates a Player for the media file by calling Manager.createRealizedPlayer
register the new Player by calling addControllerListener(listener)
prefetch the new Player then
returns the new Player
+static start(Player player): Player
Purpose: starts the input player
pre:
post: player.start() then
returns the player
+static stop(Player player): Player
Purpose: stops the player
pre:
post: if player <> null then
try
player.stop()
returns the player
catch
player.start()
else returns the player
returns the player
SoundClip
Represents a sound clip in the library
class SoundClip
Attributes:
-player: Player
-file: File
-name: String
-pathName: String
Methods:
+SoundClip(String name, String pathName)
--constructor
pre:
post: a new File object is created based on pathName and assigned to file
this.name = name
this.pathName = pathName
+load(): Boolean
pre:
post: let player = JFM.load(this.file)
if player = null then
returns true
else
returns false
+getPathname(): String
Purpose: to return a pathname
pre:
post: returns this.file.getPath()
+getName(): String
Purpose: to return a name
pre:
post: returns this.name
+getPlayer(): Player
Purpose: to return the player
pre:
post: returns this.player
PlayList
Containning set of episode objects of the Foley composition
class PlayList
Attributes:
episodes: ArrayList
Methods:
+PlayList()
--constructor
pre:
post: a new Episode is created as an ArrayList
+addEpisode(String name, Integer tm)
Purpose: a new Episode is added to the list
pre:
post: if name = null then
add a new episode object with name andm time to the next free position of the array episodes
+getEpisode(int episodeNumber): Episode
pre:
post: if the episodeNumber >= the size of the array episodes then
return null
else
return the array episodes.get(episodeNumber)
+getEpisodes(): ArrayList
pre:
post: returns the array episodes
Episode
Represents an episode in the Foley composition where the episode have a name and its starting time to be played
class Episode
Attribute:
clipName: String
time: Integer
Methods:
+Episode(String clipName, Integer time)
--Constructor
pre: There is a sound clip with name = clipName exists in the Library
post: this.clipName = clipName
this.time = time
Sequence Diagrams
Load a selected clip to the FoleyPlayer
Add sound clip to the Library
Graphical User Interface
Main FoleyPlayer interface
- The "Openning LibraryUI" button is used to open the Library user interface
- The "Record" button is used to open a recorder that allow user to record a sound
- The "Exit FTC" button is used to exit the program
- The "Play Episodes" button used to play back clips that added to the FoleyPlayer
- The "Stop Playing" button is used to stop playing back clips in the FoleyPlayer
- The "List of Episodes" column is the list of sound clips which are added to the FoleyPlayer
- The "Starting time" column is displayed the starting time of each sound clip. User can enter a strating time for a clip by clicking the row (in Starting time column) which is parralle to the clip
- User can ajust the volume in the "Control Component" panel
The Library user interface
- The "Add" button is used to add a sound clip to the Library
- The "Delete" button is used to delete a from the Library. User selects a clip from the clipNameList panel then hit the delete button
- The "Load" button is used to load a selected sound clip with a name to the FoleyPlayer. User selects a clip in the clipNamList panel then click the load button
- The "Load All" button is used to load every single clip in the clipNameList panel to the FoleyPlayer. This is designed if user wants to load all the clip at once.
The Recorded user interface
User uses this interface to record a sound
The Video interface
This is to display a movie clip which is loaded to the FoleyPlayer
Test Cases
Load clips to FoleyPlayer
Assume Foley Main Screen Loaded
1. Press the "LibraryUI" Button - Library window opens
2. Press the "Add" Button in Library Window - File window opens
3. Browse to selected a file (a clip) and click Open, then the Clip name window opens - File window closes
4. Enter a name for the clip, then press OK - Clip name window closes
5. Return to the LibraryUI window, highlight or select file (clip ID) to be loaded and click the "Load" button - The clipID is loaded to the Foley Main Screen
6. Repeat from step 2 to 5 for multi files (or clips)
Add starting time for Episodes
Assume Foley Main Screen Loaded
1. Assume files (clips) with IDs are loaded to the Foley Main Screen
2. In the "Starting Time" label (or colume), select a clip to be played that has been loaded - The "Enter Start Time" window opens
3. Type a time (in seconds >=0) for playing of track, then press the "OK" button - The "Enter Start Time" window closes
4. Repeat Steps 2&3 for multiple clips
Play Episodes
Assume Foley Main Screen Loaded
1. Check that files have been loaded to main Screen and timings set
2. Press the "Play Episodes" button to see episode play with foley sounds
Team member comments
Due to the lack of human resource (only 2 members), system tests and unit tests have not been developed. And all the sequence diagrams are not showing
Instructor comments
Initial class diagram is empty - ? I need to see more activity from this group please... thanks :) JohnR 11:30, 9 September 2006 (UTC)
Class diagram appears to have nothing to do with the rest of this documentation. Foley effects generator versus some kind of medical patient record system ???? --Dawsonj 20:27, 7 October 2006 (UTC)




