OSDN Git Service

volume コマンドを追加
authorstarg <starg@users.osdn.me>
Thu, 25 Aug 2016 13:01:44 +0000 (22:01 +0900)
committerstarg <starg@users.osdn.me>
Thu, 25 Aug 2016 13:01:44 +0000 (22:01 +0900)
include/message/id.hpp
src/driver/msgcallback.cpp
src/ir2midi/CMakeLists.txt
src/ir2midi/command_volume.cpp [new file with mode: 0644]
src/ir2midi/command_volume.hpp [new file with mode: 0644]
src/ir2midi/ir2midi.cpp

index 78b1369..a5c05d1 100644 (file)
@@ -78,8 +78,9 @@ enum class MessageID : int
     WrongNumberOfCommandArguments,
     WrongTypeOfCommandArgument,
 
+    InvalidProgram,
     InvalidTempo,
-    InvalidProgram
+    InvalidVolume
 };
 
 } // namespace Message
index f13a491..595ccf8 100644 (file)
@@ -99,8 +99,9 @@ MessagePrinter::MessagePrinter(IStdErrWriter* pStdErrWriter)
         {Message::MessageID::WrongNumberOfCommandArguments, "wrong number of arguments passed to command '{0}'; {2} expected, {1} found"},
         {Message::MessageID::WrongTypeOfCommandArgument, "command argument {1} has a wrong type; expecting '{2}' here"},
 
+        {Message::MessageID::InvalidProgram, "invalid program name"},
         {Message::MessageID::InvalidTempo, "invalid tempo value '{0}'"},
-        {Message::MessageID::InvalidProgram, "invalid program name"}
+        {Message::MessageID::InvalidVolume, "invalid volume value '{0}'"}
     },
     m_pStdErrWriter{pStdErrWriter}
 {
index e3b0cee..b691174 100644 (file)
@@ -5,11 +5,13 @@ set(IR2MIDIHeaders
     ../../include/ir2midi/ir2midi.hpp
     command_program.hpp
     command_tempo.hpp
+    command_volume.hpp
 )
 
 set(IR2MIDISources
     command_program.cpp
     command_tempo.cpp
+    command_volume.cpp
     context.cpp
     ir2midi.cpp
 )
diff --git a/src/ir2midi/command_volume.cpp b/src/ir2midi/command_volume.cpp
new file mode 100644 (file)
index 0000000..8510925
--- /dev/null
@@ -0,0 +1,111 @@
+
+#include <memory>
+#include <typeinfo>
+
+#include <ast/composition.hpp>
+#include <ir2midi/command.hpp>
+#include <ir2midi/context.hpp>
+#include <message/id.hpp>
+#include <midi/event.hpp>
+#include <midi/limits.hpp>
+
+#include "command_volume.hpp"
+
+
+namespace YAMML
+{
+
+namespace IR2MIDI
+{
+
+class VolumeCommandProcessor final : public ICommandProcessor
+{
+public:
+    explicit VolumeCommandProcessor(IIR2MIDICompiler* pCompiler) : m_pCompiler(pCompiler)
+    {
+    }
+
+    virtual ~VolumeCommandProcessor() = default;
+
+    virtual IIR2MIDICompiler* GetCompiler() override
+    {
+        return m_pCompiler;
+    }
+
+    virtual void Process(const AST::Command& ast) override
+    {
+        ValidateArguments(ast);
+
+        auto channel = boost::get<long>(ast.Arguments[0].Value);
+        auto volume = boost::get<long>(ast.Arguments[1].Value);
+
+        GetCompiler()->GetTrackContext(channel).PushEvent(
+            0,
+            MIDI::ControlChange{channel, MIDI::ControllerNumber::MainVolume, volume}
+        );
+    }
+
+    void ValidateArguments(const AST::Command& ast)
+    {
+        if (ast.Arguments.size() != 2)
+        {
+            ThrowMessage(
+                Message::MessageID::WrongNumberOfCommandArguments,
+                ast.Location,
+                {"volume", std::to_string(ast.Arguments.size()), "2"}
+            );
+        }
+
+        if (ast.Arguments[0].Value.type() != typeid(long))
+        {
+            ThrowMessage(
+                Message::MessageID::WrongTypeOfCommandArgument,
+                ast.Location,
+                {"volume", "1", "int"}
+            );
+        }
+
+        if (ast.Arguments[1].Value.type() != typeid(long))
+        {
+            ThrowMessage(
+                Message::MessageID::WrongTypeOfCommandArgument,
+                ast.Location,
+                {"volume", "2", "int"}
+            );
+        }
+
+        auto channel = boost::get<long>(ast.Arguments[0].Value);
+
+        if (!(0 <= channel && channel < MIDI::TrackNumberLimit))
+        {
+            ThrowMessage(
+                Message::MessageID::TrackNumberIsOutOfPreferredRange,
+                ast.Location,
+                {std::to_string(channel), std::to_string(MIDI::TrackNumberLimit)}
+            );
+        }
+
+        auto volume = boost::get<long>(ast.Arguments[1].Value);
+
+        if (!(0 <= volume && volume < 128))
+        {
+            ThrowMessage(
+                Message::MessageID::InvalidVolume,
+                ast.Location,
+                {std::to_string(channel)}
+            );
+        }
+    }
+
+private:
+    IIR2MIDICompiler* m_pCompiler;
+};
+
+std::unique_ptr<ICommandProcessor> CreateVolumeCommandProcessor(IIR2MIDICompiler* pCompiler)
+{
+    return std::make_unique<VolumeCommandProcessor>(pCompiler);
+}
+
+} // namespace IR2MIDI
+
+} // namespace YAMML
diff --git a/src/ir2midi/command_volume.hpp b/src/ir2midi/command_volume.hpp
new file mode 100644 (file)
index 0000000..775887b
--- /dev/null
@@ -0,0 +1,19 @@
+
+#pragma once
+
+#include <memory>
+
+#include <ir2midi/command.hpp>
+#include <ir2midi/context.hpp>
+
+namespace YAMML
+{
+
+namespace IR2MIDI
+{
+
+std::unique_ptr<ICommandProcessor> CreateVolumeCommandProcessor(IIR2MIDICompiler* pCompiler);
+
+} // namespace IR2MIDI
+
+} // namespace YAMML
index 03524c3..b50a05c 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "command_program.hpp"
 #include "command_tempo.hpp"
+#include "command_volume.hpp"
 
 namespace YAMML
 {
@@ -193,6 +194,7 @@ void IR2MIDICompiler::InitializeCommandProcessors()
 {
     m_CommandProcessors["program"] = CreateProgramCommandProcessor(this);
     m_CommandProcessors["tempo"] = CreateTempoCommandProcessor(this);
+    m_CommandProcessors["volume"] = CreateVolumeCommandProcessor(this);
 }
 
 bool IR2MIDICompiler::CompileTrackBlock(const std::string& trackBlockName)