Skip to content

Commit

Permalink
Added Part, Score and MIDIPlayer
Browse files Browse the repository at this point in the history
Also, edited some other files + started work on pipeline
  • Loading branch information
RandyParedis committed Oct 27, 2018
1 parent 065af7a commit 2f59309
Show file tree
Hide file tree
Showing 13 changed files with 511 additions and 96 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
set(PROJECT_NAME autoplay)
project(${PROJECT_NAME})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14 ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11 ")

if(APPLE)
string(APPEND CMAKE_CXX_FLAGS "-D__MACOSX_CORE__ ")
Expand All @@ -25,7 +25,7 @@ add_subdirectory(main)
target_include_directories(autoplay PUBLIC ${TRNG_LOCATION}/include)
target_include_directories(autoplay PUBLIC ${TRNG_LOCATION}/lib)
target_include_directories(autoplay PUBLIC ${DEPENDENCY_DIR})
target_include_directories(autoplay PUBLIC ${DEPENDENCY_DIR}/zupply/src)
#target_include_directories(autoplay PUBLIC ${DEPENDENCY_DIR}/zupply/src)
target_include_directories(autoplay PUBLIC ${Boost_INCLUDE_DIRS})

add_subdirectory(test)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@ compile `cmake` of this project with the flag `-DTRNG_LOC` set to your home dire
| 21-10-2018 | Added `Clef` and `Measure` class and added tests for the latter.
| 23-10-2018 | Added `zupply` for logging.
| 24-10-2018 | Started work on `Instrument` class, by using a very basic implementation. Currently, only piano instruments are implemented in the `music::instruments` namespace, but this is enough for the current working version.<br>Also added a `music::instruments::findByName(const std::string&)` function to find an instrument by name (precursor to config file support).
| 27-10-2018 | Added `Part`, `Score` and `MIDIPlayer` classes.
6 changes: 5 additions & 1 deletion main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ set(autoplay_SRC
music/Measure.h
music/Clef.h
music/Instrument.h
music/Instrument.cpp)
music/Instrument.cpp
music/Part.h
music/Score.h
music/MIDIPlayer.cpp
music/MIDIPlayer.h)

add_library(autoplay ${autoplay_SRC})

Expand Down
126 changes: 61 additions & 65 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//

#include <rtmidi/RtMidi.h>
#include <zupply/src/zupply.hpp>

#include <iostream>
#include <cstdlib>
Expand All @@ -14,79 +15,74 @@
#include "music/Note.h"
#include "util/Randomizer.h"
#include "music/Instrument.h"
#include "music/MIDIPlayer.h"

#include <trng/mrg2.hpp>

#define SLEEP( milliseconds ) usleep( (unsigned long) ((milliseconds) * 1000.0) )

int probe()
{
// Create an api map.
std::map<int, std::string> apiMap;
apiMap[RtMidi::MACOSX_CORE] = "OS-X CoreMidi";
apiMap[RtMidi::WINDOWS_MM] = "Windows MultiMedia";
apiMap[RtMidi::UNIX_JACK] = "Jack Client";
apiMap[RtMidi::LINUX_ALSA] = "Linux ALSA";
apiMap[RtMidi::RTMIDI_DUMMY] = "RtMidi Dummy";

std::vector< RtMidi::Api > apis;
RtMidi :: getCompiledApi( apis );

std::cout << "\nCompiled APIs:\n";
for ( unsigned int i=0; i<apis.size(); i++ )
std::cout << " " << apiMap[ apis[i] ] << std::endl;

RtMidiIn *midiin = 0;
RtMidiOut *midiout = 0;

try {

// RtMidiIn constructor ... exception possible
midiin = new RtMidiIn();

std::cout << "\nCurrent input API: " << apiMap[ midiin->getCurrentApi() ] << std::endl;

// Check inputs.
unsigned int nPorts = midiin->getPortCount();
std::cout << "\nThere are " << nPorts << " MIDI input sources available.\n";

for ( unsigned i=0; i<nPorts; i++ ) {
std::string portName = midiin->getPortName(i);
std::cout << " Input Port #" << i+1 << ": " << portName << '\n';
}

// RtMidiOut constructor ... exception possible
midiout = new RtMidiOut();

std::cout << "\nCurrent output API: " << apiMap[ midiout->getCurrentApi() ] << std::endl;

// Check outputs.
nPorts = midiout->getPortCount();
std::cout << "\nThere are " << nPorts << " MIDI output ports available.\n";

for ( unsigned i=0; i<nPorts; i++ ) {
std::string portName = midiout->getPortName(i);
std::cout << " Output Port #" << i+1 << ": " << portName << std::endl;
}
std::cout << std::endl;

} catch ( RtMidiError &error ) {
error.printMessage();
}

delete midiin;
delete midiout;

return 0;
}

int main()
{
// trng::mrg2 engine;
// engine.seed(10);
// std::cout << Randomizer::pick_uniform(engine, 0.0f, 100.0f) << std::endl;
probe();
RtMidiOut *midiout = new RtMidiOut();

// Create the Logger
zz::log::LogConfig::instance().set_format("[%datetime][%level]\t%msg");
auto logger = zz::log::get_logger("system_logger");
logger->info("Started autoplayer");

// Probe information
std::shared_ptr<music::MIDIPlayer> midiPlayer = music::MIDIPlayer::instance();
midiPlayer->probe(logger);

music::Measure measure(music::Clef::Treble(), {4, 4}, 24);
std::vector<uint8_t> pitches = {
music::Note::pitch("E4"),
music::Note::pitch("E4"),
music::Note::pitch("F4"),
music::Note::pitch("G4"),
music::Note::pitch("G4"),
music::Note::pitch("F4"),
music::Note::pitch("E4"),
music::Note::pitch("D4"),
music::Note::pitch("C4"),
music::Note::pitch("C4"),
music::Note::pitch("D4"),
music::Note::pitch("E4"),
music::Note::pitch("E4"),
music::Note::pitch("D4"),
music::Note::pitch("D4"),

music::Note::pitch("E4"),
music::Note::pitch("E4"),
music::Note::pitch("F4"),
music::Note::pitch("G4"),
music::Note::pitch("G4"),
music::Note::pitch("F4"),
music::Note::pitch("E4"),
music::Note::pitch("D4"),
music::Note::pitch("C4"),
music::Note::pitch("C4"),
music::Note::pitch("D4"),
music::Note::pitch("E4"),
music::Note::pitch("D4"),
music::Note::pitch("C4"),
music::Note::pitch("C4")
};
for(const auto& pitch: pitches) {
music::Note n{pitch, 24};
measure.append(n);
}
music::Instrument instrument = music::instruments::acoustic_grand_piano;
std::shared_ptr<music::Part> part = std::make_shared<music::Part>(&instrument);
part->setMeasures(measure);
music::Score score;
score.parts.emplace_back(part);

midiPlayer->play(score, logger);

/*RtMidiOut *midiout = new RtMidiOut();
std::vector<unsigned char> message;
// Check available ports.
unsigned int nPorts = midiout->getPortCount();
Expand All @@ -106,7 +102,7 @@ int main()
message[0] = 0xF1; // MIDI Time Code Quarter Frame
message[1] = 60;
midiout->sendMessage( &message );
// midiout->sendMessage( &message );
SLEEP( 500 );
Expand Down Expand Up @@ -184,5 +180,5 @@ int main()
}
delete midiout;
return 0;
return 0;*/
}
93 changes: 76 additions & 17 deletions main/music/Instrument.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,101 @@
#include <vector>

namespace music {
/**
* The Instrument class handles all simple actions concerned to instruments and the way certain things sound.
*/
class Instrument {
public:
/**
* Default Constructor
* @param name The name (as string) of an Instrument
* @param channel The channel of the Instrument
* @param program The program of the Instrument
* @param unpitched The index of the MIDI sound corresponding to the Instrument
*/
Instrument(const std::string& name, uint8_t channel, uint8_t program, uint8_t unpitched) :
m_name(name), m_channel(channel), m_program(program), m_unpitched(unpitched) {}

/**
* Gets the name of the Instrument
* @return The name
*/
inline std::string getName() const { return m_name; }

/**
* Gets the channel of the Instrument
* @return The channel
*/
inline uint8_t getChannel() const { return m_channel; }

/**
* Gets the program of the Instrument
* @return The program
*/
inline uint8_t getProgram() const { return m_program; }

/**
* Gets the unpitched value of the Instrument
* @return The unpitched value (index)
*/
inline uint8_t getUnpitched() const { return m_unpitched; }

/**
* Sets the name of the Instrument
* @param name New name to set
*/
inline void setName(const std::string& name) { m_name = name; }

/**
* Sets the channel of the Instrument
* @param channel New channel to set
*/
inline void setChannel(const uint8_t& channel) { m_channel = channel; }

/**
* Sets the program of the Instrument
* @param program New program to set
*/
inline void setProgram(const uint8_t& program) { m_program = program; }

/**
* Sets the unpitched of the Instrument
* @param unpitched New unpitched to set
*/
inline void setUnpitched(const uint8_t& unpitched) { m_unpitched = unpitched; }

private:
std::string m_name;
uint8_t m_channel;
uint8_t m_program;
uint8_t m_unpitched; ///< The tone that must be played. In the MusicXML, we start counting from 1!
std::string m_name; ///< The name of the Instrument
uint8_t m_channel; ///< The channel of the Instrument
uint8_t m_program; ///< The program of the Instrument
uint8_t m_unpitched; ///< The tone that must be played. In the MusicXML, we start counting from 1!
};

/**
* The instruments namespace contains all existing music instruments in MIDI as Instrument objects.
*
* @note Currently, merely the piano-like Instruments are implemented
*
* TODO: Implement all Instruments
*/
namespace instruments {
/// Instruments

// Pianos
Instrument acoustic_grand_piano{"Acoustic Grand Piano", 1, 1, 1};
Instrument bright_acoustic_piano{"Bright Acoustic Piano", 1, 1, 2};
Instrument electric_grand_piano{"Electric Grand Piano", 1, 1, 3};
Instrument honky_tonk_piano{"Honky-tonk Piano", 1, 1, 4};
Instrument electric_piano1{"Electric Piano 1", 1, 1, 5};
Instrument electric_piano2{"Electric Piano 2", 1, 1, 6};
Instrument hapsichord{"Hapsichord", 1, 1, 7};
Instrument clavinet{"Clavinet", 1, 1, 8};

std::vector<Instrument*> all = {

/// Pianos

static Instrument acoustic_grand_piano{"Acoustic Grand Piano", 1, 1, 1};
static Instrument bright_acoustic_piano{"Bright Acoustic Piano", 1, 1, 2};
static Instrument electric_grand_piano{"Electric Grand Piano", 1, 1, 3};
static Instrument honky_tonk_piano{"Honky-tonk Piano", 1, 1, 4};
static Instrument electric_piano1{"Electric Piano 1", 1, 1, 5};
static Instrument electric_piano2{"Electric Piano 2", 1, 1, 6};
static Instrument hapsichord{"Hapsichord", 1, 1, 7};
static Instrument clavinet{"Clavinet", 1, 1, 8};

/**
* The all vector is a list of all the above instruments, indexable by 0, or by name,
* using the findByName function below.
*/
static std::vector<Instrument*> all = {
&acoustic_grand_piano, &bright_acoustic_piano, &electric_grand_piano, &honky_tonk_piano,
&electric_piano1, &electric_piano2, &hapsichord, &clavinet
};
Expand Down
Loading

0 comments on commit 2f59309

Please sign in to comment.