java program
doublylinkedlist/DoublyLinkedList.java
doublylinkedlist/DoublyLinkedList.java
public
class
DoublyLinkedList
{
Node
start
;
int
length
;
public
DoublyLinkedList
(){
this
.
start
=
null
;
this
.
length
=
0
;
}
// find if the value exists in the list
// if it does, return the first node that matches
// return null otherwise
public
Node
find
(
String
value
){
// TODO
return
null
;
}
// insert a new node at the beginning of the list
public
void
insertStart
(
String
value
){
// TODO create a node with the input value and add it to the list
}
// insert a new node at the end of the list
public
void
insertEnd
(
String
value
){
// TODO create a node with the input value and add it to the list
}
// remove all the occurences of the value in the list
public
void
remove
(
String
value
){
// TODO
}
// remove from the list the Node at the position given
// by the value of index.
public
void
removeAtIndex
(
int
index
){
// TODO
}
// print the string in reverse order
public
String
toStringReverse
(){
String
result
=
""
;
// TODO
return
result
;
}
// print the string
public
String
toString
(){
String
str
=
""
;
Node
pointer
=
this
.
start
;
while
(
pointer
!=
null
)
{
str
+=
pointer
.
toString
();
pointer
=
pointer
.
next
;
}
return
str
;
}
public
static
void
main
(
String
[]
args
){
DoublyLinkedList
list
=
new
DoublyLinkedList
();
String
once
=
"And you may find yourself "
;
list
.
insertStart
(
"I am helpless. "
);
list
.
insertEnd
(
once
);
list
.
insertEnd
(
"I do not believe "
);
list
.
insertEnd
(
"Hello!. "
);
list
.
insertEnd
(
"There is hope. "
);
Node
n
=
list
.
find
(
once
);
n
.
data
+=
" in a shotgun shack."
;
System
.
out
.
println
(
list
);
list
.
remove
(
once
);
list
.
removeAtIndex
(
4
);
System
.
out
.
println
(
list
);
System
.
out
.
println
(
list
.
toStringReverse
());
}
}
doublylinkedlist/Node.java
doublylinkedlist/Node.java
public
class
Node
{
// TODO modify this class so that it
// stores a reference to the previous
// element in the list
String
data
;
Node
next
;
public
Node
(
String
input_data
){
this
.
data
=
input_data
;
this
.
next
=
null
;
}
}
music/MidiNote.java
music/MidiNote.java
public
class
MidiNote
{
// This is a number corresponding to the pitch value
// of this note. This follows the MIDI numbering
// from 21 ( an A0 note ) to 108 ( a C8 note )
private
int
pitch
=
60
;
// This is the duration of this note in beats
private
int
duration
=
1
;
// This determines if this note gets played, or
// if this represents a silence of a particular
// duration.
private
boolean
silent
=
false
;
public
MidiNote
(
int
pitch
,
int
duration
){
this
.
setPitch
(
pitch
);
this
.
setDuration
(
duration
);
// minimum duration for a note is 1 beat
if
(
this
.
duration
<=
0
){
this
.
duration
=
1
;
}
}
// GETTER METHODS
public
int
getPitch
(){
return
pitch
;
}
public
int
getDuration
(){
return
duration
;
}
public
boolean
isSilent
(){
return
silent
;
}
// This method will tell you how many octaves up or down
// this note is. A value of 0 means that the note is in the
// range from 60 ( a C4 note ) to 71 ( a B4 note )
public
int
getOctave
(){
int
octave
=
(
int
)
(
Math
.
floor
((
this
.
pitch
-
60.0
)
/
12.0
));
return
octave
;
}
// SETTER METHODS
public
boolean
setPitch
(
int
pitch
){
if
(
pitch
<
21
){
if
(
pitch
==
0
){
this
.
pitch
=
0
;
return
true
;
}
this
.
pitch
=
21
;
}
else
if
(
pitch
<=
108
)
{
this
.
pitch
=
pitch
;
return
true
;
}
else
{
this
.
pitch
=
108
;
}
System
.
out
.
println
(
"Pitch "
+
pitch
+
" out of valid range [ 21 to 108 ]!"
);
return
false
;
}
public
boolean
setDuration
(
int
duration
){
if
(
duration
>
0
){
this
.
duration
=
duration
;
return
true
;
}
return
false
;
}
public
void
setSilent
(
boolean
value
){
this
.
silent
=
value
;
}
// toString method. Useful for debugging your code
public
String
toString
(){
return
"( duration: "
+
duration
+
", pitch: "
+
pitch
+
", silent: "
+
silent
+
" )"
;
}
public
int
getVolume
(){
return
64
;
}
}
music/MidiTrack.java
music/MidiTrack.java
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Hashtable
;
public
class
MidiTrack
{
private
Hashtable
<
Character
,
Integer
>
noteToPitch
;
private
ArrayList
<
MidiNote
>
notes
;
private
int
instrumentId
;
// The constructor for this class
public
MidiTrack
(
int
instrumentId
){
notes
=
new
ArrayList
<
MidiNote
>
();
this
.
instrumentId
=
instrumentId
;
this
.
initPitchDictionary
();
}
// This initialises the noteToPitch dictionary,
// which will be used by you to convert note letters
// to pitch numbers
public
void
initPitchDictionary
(){
noteToPitch
=
new
Hashtable
<
Character
,
Integer
>
();
noteToPitch
.
put
(
'C'
,
60
);
noteToPitch
.
put
(
'D'
,
62
);
noteToPitch
.
put
(
'E'
,
64
);
noteToPitch
.
put
(
'F'
,
65
);
noteToPitch
.
put
(
'G'
,
67
);
noteToPitch
.
put
(
'A'
,
69
);
noteToPitch
.
put
(
'B'
,
71
);
}
// GETTER METHODS
public
ArrayList
<
MidiNote
>
getNotes
(){
return
notes
;
}
public
int
getInstrumentId
(){
return
instrumentId
;
}
// This method converts notestrings like
// <<3E3P2E2GP2EPDP8C<8B>
// to an ArrayList of MidiNote objects
// ( the notes attribute of this class )
public
void
loadNoteString
(
String
notestring
){
// convert the letters in the notestring to upper case
notestring
=
notestring
.
toUpperCase
();
int
duration
=
0
;
int
pitch
=
0
;
int
octave
=
0
;
// TODO: Q2. implement this method
// Q2.a. Notes
// Q2.b. Pauses
// Q2.c. Durations
// Q2.d. Octaves
// Q2.e. Flat and sharp notes
// Hint1: use a for loop with conditional statements
// Hint2: Use the get method of the noteToPitch object (Hashtable class)
}
public
void
revert
(){
ArrayList
<
MidiNote
>
reversedTrack
=
new
ArrayList
<
MidiNote
>
();
for
(
int
i
=
notes
.
size
()
-
1
;
i
>=
0
;
i
--
){
MidiNote
oldNote
=
notes
.
get
(
i
);
// create a newNote
MidiNote
newNote
=
new
MidiNote
(
oldNote
.
getPitch
(),
oldNote
.
getDuration
());
// check if the note was a pause
if
(
oldNote
.
isSilent
()){
newNote
.
setSilent
(
true
);
}
// add the note to the new arraylist
reversedTrack
.
add
(
newNote
);
}
notes
=
reversedTrack
;
}
// This will only be called if you try to run this file directly
// You may use this to test your code.
public
static
void
main
(
String
[]
args
){
String
notestring
=
"<<3E3P2E2GP2EPDP8C<8B>3E3P2E2GP2EPDP8C<8B>"
;
// Build the MidiTrack object
// Build a MusicInterpreter and set a playing speed
// Load the track and play it
// Close the player so that your program terminates
}
}
music/MusicInterpreter.java
music/MusicInterpreter.java
import
java
.
io
.
File
;
import
java
.
io
.
IOException
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Hashtable
;
import
javax
.
sound
.
midi
.
Instrument
;
import
javax
.
sound
.
midi
.
InvalidMidiDataException
;
import
javax
.
sound
.
midi
.
MidiEvent
;
import
javax
.
sound
.
midi
.
MidiSystem
;
import
javax
.
sound
.
midi
.
MidiUnavailableException
;
import
javax
.
sound
.
midi
.
Sequence
;
import
javax
.
sound
.
midi
.
Sequencer
;
import
javax
.
sound
.
midi
.
ShortMessage
;
import
javax
.
sound
.
midi
.
Soundbank
;
import
javax
.
sound
.
midi
.
Synthesizer
;
import
javax
.
sound
.
midi
.
Track
;
public
class
MusicInterpreter
{
Sequencer
sequencer
;
Sequence
sequence
;
Synthesizer
synthesizer
;
Track
currentTrack
;
Instrument
[]
instruments
;
long
startTime
=
System
.
currentTimeMillis
();
public
MusicInterpreter
()
{
try
{
// get a copy of the default system synthesizer
synthesizer
=
MidiSystem
.
getSynthesizer
();
synthesizer
.
open
();
// get the current instruments
instruments
=
synthesizer
.
getAvailableInstruments
();
// Get the default system sequencer
sequencer
=
MidiSystem
.
getSequencer
(
false
);
sequencer
.
open
();
sequencer
.
setTempoInBPM
(
200
);
sequencer
.
getTransmitter
().
setReceiver
(
synthesizer
.
getReceiver
());
// set the resolution to 1 tick per quarter note
sequence
=
new
Sequence
(
Sequence
.
PPQ
,
1
);
}
catch
(
MidiUnavailableException
e
)
{
e
.
printStackTrace
();
}
catch
(
InvalidMidiDataException
e
)
{
e
.
printStackTrace
();
}
}
public
void
close
(){
synthesizer
.
close
();
sequencer
.
close
();
}
public
void
loadSoundBank
(
String
path
)
{
try
{
File
f
=
new
File
(
path
);
Soundbank
sb
=
MidiSystem
.
getSoundbank
(
f
);
if
(
synthesizer
.
isSoundbankSupported
(
sb
)){
// unload all instruments
for
(
Instrument
i
:
instruments
){
synthesizer
.
unloadInstrument
(
i
);
}
synthesizer
.
loadAllInstruments
(
sb
);
instruments
=
synthesizer
.
getLoadedInstruments
();
}
sequencer
.
getTransmitter
().
setReceiver
(
synthesizer
.
getReceiver
());
System
.
out
.
println
(
". Loaded "
+
(
sb
.
getName
())
+
" soundbank"
);
}
catch
(
InvalidMidiDataException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
MidiUnavailableException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
instruments
=
synthesizer
.
getLoadedInstruments
();
System
.
out
.
println
(
availableInstruments
());
}
private
void
selectInstrument
(
int
instrumentId
,
int
channel
)
{
System
.
out
.
println
(
".. Loading "
+
instruments
[
instrumentId
].
getName
());
Instrument
i
=
instruments
[
instrumentId
];
synthesizer
.
loadInstrument
(
i
);
int
bank
=
i
.
getPatch
().
getProgram
();
createEvent
(
ShortMessage
.
CONTROL_CHANGE
,
channel
,
bank
,
0
,
0
);
createEvent
(
ShortMessage
.
CONTROL_CHANGE
,
channel
,
bank
>>
8
,
0
,
0
);
createEvent
(
ShortMessage
.
PROGRAM_CHANGE
,
channel
,
i
.
getPatch
().
getProgram
(),
0
,
0
);
}
public
String
availableInstruments
()
{
String
str
=
""
;
int
i
=
0
;
for
(
Instrument
inst
:
instruments
)
{
str
+=
".. "
+
(
i
++
)
+
" - "
+
inst
.
getName
()
+
"\n"
;
}
return
str
;
}
public
void
loadTracks
(
ArrayList
<
MidiTrack
>
tracks
)
{
int
channel
=
0
;
// delete the previous tracks
Track
[]
oldTracks
=
sequence
.
getTracks
();
for
(
Track
t
:
oldTracks
){
sequence
.
deleteTrack
(
t
);
}
// add the new ones
for
(
MidiTrack
midiTrack
:
tracks
)
{
loadSingleTrack
(
midiTrack
,
channel
);
channel
++
;
}
System
.
out
.
println
(
". Loaded "
+
(
channel
)
+
" tracks"
);
}
public
void
loadSingleTrack
(
MidiTrack
midiTrack
){
loadSingleTrack
(
midiTrack
,
sequence
.
getTracks
().
length
);
}
public
void
loadSingleTrack
(
MidiTrack
midiTrack
,
int
channel
){
currentTrack
=
sequence
.
createTrack
();
selectInstrument
(
midiTrack
.
getInstrumentId
(),
channel
);
int
currentTick
=
1
;
for
(
MidiNote
note
:
midiTrack
.
getNotes
())
{
if
(
!
note
.
isSilent
()){
createEvent
(
ShortMessage
.
NOTE_ON
,
channel
,
note
.
getPitch
(),
note
.
getVolume
(),
currentTick
);
createEvent
(
ShortMessage
.
NOTE_OFF
,
channel
,
note
.
getPitch
(),
note
.
getVolume
(),
currentTick
+
note
.
getDuration
());
}
currentTick
+=
note
.
getDuration
();
}
channel
++
;
System
.
out
.
println
(
".. Loading track "
+
channel
);
}
public
void
loadSong
(
Song
song
)
{
System
.
out
.
println
(
"Loading Song: "
+
song
.
getName
());
if
(
song
.
getSoundbank
().
length
()
>
0
){
// load a soundbank, if one was specified in the Song file
loadSoundBank
(
song
.
getSoundbank
());
}
setBPM
(
song
.
getBPM
());
loadTracks
(
song
.
getTracks
());
}
public
void
play
()
{
System
.
out
.
println
(
"Playing music!"
);
try
{
sequencer
.
open
();
}
catch
(
MidiUnavailableException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
}
try
{
sequencer
.
setSequence
(
sequence
);
}
catch
(
InvalidMidiDataException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
sequencer
.
start
();
// make the program wait until the sequence has been played
long
sequence_length_millis
=
(
long
)(
60000
*
sequence
.
getTickLength
()
/
sequencer
.
getTempoInBPM
())
+
1
;
try
{
Thread
.
sleep
(
sequence_length_millis
+
1000
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
sequencer
.
stop
();
System
.
out
.
println
(
"Finished playing music!"
);
}
public
void
setBPM
(
int
bpm
)
{
sequencer
.
setTempoInBPM
(
bpm
);
}
public
void
createEvent
(
int
type
,
int
chan
,
int
num
,
int
vel
,
long
tick
)
{
ShortMessage
message
=
new
ShortMessage
();
try
{
message
.
setMessage
(
type
,
chan
,
num
,
vel
);
MidiEvent
event
=
new
MidiEvent
(
message
,
tick
);
currentTrack
.
add
(
event
);
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
}
}
}
music/PlaySong.java
music/PlaySong.java
import
java
.
io
.
FileNotFoundException
;
import
java
.
io
.
IOException
;
import
java
.
util
.
Scanner
;
public
class
PlaySong
{
public
static
void
main
(
String
[]
args
){
MusicInterpreter
myMusicPlayer
=
new
MusicInterpreter
();
// uncomment this line to print the available instruments
//System.out.println(myMusicPlayer.availableInstruments());
// TODO: Q3. b
// Create a Song object
// load text file using the given song_filename,
// remember to catch the appropriate Exceptions
// Play it
}
}
music/Song.java
music/Song.java
import
java
.
io
.
BufferedReader
;
import
java
.
io
.
File
;
import
java
.
io
.
FileNotFoundException
;
import
java
.
io
.
IOException
;
import
java
.
io
.
FileReader
;
import
java
.
util
.
ArrayList
;
public
class
Song
{
String
myName
;
int
myBeatsPerMinute
;
String
mySoundbank
;
ArrayList
<
MidiTrack
>
myTracks
;
// The constructor of this class
public
Song
(){
myTracks
=
new
ArrayList
<
MidiTrack
>
();
myBeatsPerMinute
=
200
;
mySoundbank
=
""
;
myName
=
"Default_Name"
;
}
// GETTER METHODS
public
String
getName
(){
return
myName
;
}
public
String
getSoundbank
(){
return
mySoundbank
;
}
public
int
getBPM
(){
return
myBeatsPerMinute
;
}
public
ArrayList
<
MidiTrack
>
getTracks
(){
return
myTracks
;
}
// TODO: Q3.a.
// Implement void loadFromFile(String file_path) method
// This method loads the properties and build the tracks of this
// song object from a file in the location specified by
// file
public
void
revert
(){
for
(
int
i
=
0
;
i
<
myTracks
.
size
();
i
++
){
myTracks
.
get
(
i
).
revert
();
}
}
}
music/SongWriter.java
music/SongWriter.java
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Hashtable
;
import
java
.
io
.
FileWriter
;
import
java
.
io
.
BufferedWriter
;
import
java
.
io
.
FileNotFoundException
;
import
java
.
io
.
IOException
;
import
java
.
util
.
Scanner
;
public
class
SongWriter
{
private
Hashtable
<
Integer
,
String
>
pitchToNote
;
// The constructor of this class
public
SongWriter
(){
this
.
initPitchToNoteDictionary
();
}
// This initialises the pitchToNote dictionary,
// which will be used by you to convert pitch numbers
// to note letters
public
void
initPitchToNoteDictionary
(){
pitchToNote
=
new
Hashtable
<
Integer
,
String
>
();
pitchToNote
.
put
(
60
,
"C"
);
pitchToNote
.
put
(
61
,
"C#"
);
pitchToNote
.
put
(
62
,
"D"
);
pitchToNote
.
put
(
63
,
"D#"
);
pitchToNote
.
put
(
64
,
"E"
);
pitchToNote
.
put
(
65
,
"F"
);
pitchToNote
.
put
(
66
,
"F#"
);
pitchToNote
.
put
(
67
,
"G"
);
pitchToNote
.
put
(
68
,
"G#"
);
pitchToNote
.
put
(
69
,
"A"
);
pitchToNote
.
put
(
70
,
"A#"
);
pitchToNote
.
put
(
71
,
"B"
);
}
// This method converts a single MidiNote to its notestring representation
public
String
noteToString
(
MidiNote
note
){
String
result
=
""
;
// TODO: Q4.a.
return
result
;
}
// This method converts a MidiTrack to its notestring representation.
// You should use the noteToString method here
public
String
trackToString
(
MidiTrack
track
){
ArrayList
<
MidiNote
>
notes
=
track
.
getNotes
();
String
result
=
""
;
int
previous_octave
=
0
;
MidiNote
current_note
;
// TODO: Q4.b.
/*
* A hint for octaves: if the octave of the previous MidiNote was -1
* and the octave of the current MidiNote is +3, we will have
* to append ">>>>" to the result string.
*/
return
result
;
}
// TODO Q4.c.
// Implement the void writeToFile( Song s1 , String file_path) method
// This method writes the properties of the Song s1 object
// and writes them into a file in the location specified by
// file_path. This file should have the same format as the sample
// files in the 'data/' folder.
public
static
void
main
(
String
[]
args
){
// TODO: Q4.d.
// Create a Song object
// Load text file using the given song_filename, remember to
// catch the appropriate Exceptions, print meaningful messages!
// e.g. if the file was not found, print "The file FILENAME_HERE was not found"
// call the revert method of the song object.
// Create a SongWriter object here, and call its writeToFile( Song s, String file_location) method.
}
}
music/data/01.txt
bpm = 100 name = simple track = CDEFGAB
music/data/02.txt
bpm = 250 name = canada soundbank = ./data/soundbanks/Famicom.sf2 instrument = 1 track = 4E3GG4C2P2D2E2F2G2A6D
music/data/03.txt
bpm = 1150 name = video instrument = 30 track = 4E4G8G8G4G8G4A8F12F4P4E4G8G8G4G8G4A8F12F4P4E8E12D8D4F8C12C4P4C8E8E8D8D4F8C12C
music/data/04.txt
bpm = 240 name = ricercar soundbank = ./data/soundbanks/nes.sf2 instrument = 32 track = 4C4D#4G4G#<6B>2G4F#4F4E6D#2D2C#2C<2BAG>2C2F4D#4D6C
music/data/05.txt
bpm = 280 name = simple_poly instrument = 0 track = <10c track = <10g track = cdefed2c2g
music/data/06.txt
bpm = 240 name = ricercar2 instrument = 0 track = >4C4D#4G4G#<6B>2G4F#4F4E6D#2D2C#2C<2BAG>2C2F4D#4D6C instrument = 0 track = 4C4G4D#2F2C<GA2B>4C2C#2D6D#4E4F4F#2G<4B>4G#4G4D#6C
music/data/07.txt
bpm = 1200 name = underworld soundbank = ./data/soundbanks/Famicom.sf2 instrument = 5 track = 3C>3C<<3A>3A<3A#>3A#18P3C>3C<<3A>3A<3A#>3A#18P<3F>3F<3D>3D<3D#>3D#18P<3F>3F<3D>3D<3D#>3D#12P2D#2D2C#3C3P3D#3P3D3P<3G#3P3G3P>3C#3P2C2F#2F2E2A#2A2G#2P2D#2P<2B#2P2A#2P2A2P2G# instrument = 6 track = <3C3C<3A3A3A#3A#18P>3C3C<3A3A3A#3A#18P3F3F3D3D3D#3D#18P3F3F3D3D3D#3D#12P2D#2D2C#3C3P3D#3P3D3P<3G#3P3G3P>3C#3P2C2F#2F2E2A#2A2G#2P2D#2P<2B#2P2A#2P2A2P2G#
music/data/08.txt
bpm = 280 name = phil_collins instrument = 0 track = 2p16c<7a8a>7c8c8d instrument = 0 track = 2p16e7d8c7e8f8g instrument = 0 track = 2p16g7f8e7g8a8b instrument = 0 track = >cc2cc2c2c2c4p<2b>c2dc2c<2b>c<2a>4pc2cc2c2c2f2e2c2d8d