mirror of
https://github.com/yokemura/Magical8bitPlug2.git
synced 2025-05-24 23:00:21 -04:00
(1)Added test class (2)Use separated findSegment method
This commit is contained in:
parent
ad947fcfda
commit
846133ac39
@ -10,6 +10,10 @@
|
||||
pluginDesc="8bit sound generator 2nd ver. by YMCK" displaySplashScreen="1"
|
||||
jucerFormatVersion="1" version="1.0.1">
|
||||
<MAINGROUP id="tlJ5Jv" name="Magical8bitPlug2">
|
||||
<GROUP id="{90CFFF6B-201B-9373-6BE8-DDF2F136949F}" name="Tests">
|
||||
<FILE id="WZca8g" name="EnvelopeParserTest.h" compile="0" resource="0"
|
||||
file="Source/EnvelopeParserTest.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{05934500-901F-8317-27DC-7E17FC00833D}" name="View">
|
||||
<GROUP id="{68A7410F-88F9-C9D8-8A37-6A70F269BBCC}" name="BaseComponents">
|
||||
<FILE id="lBYKKS" name="CheckBoxComponent.cpp" compile="1" resource="0"
|
||||
|
90
Source/EnvelopeParserTest.h
Normal file
90
Source/EnvelopeParserTest.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
EnvelopeParserTest.h
|
||||
Created: 13 Aug 2021 6:14:32pm
|
||||
Author: 除村武志
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "FrameSequence.h"
|
||||
#include "FrameSequenceParser.h"
|
||||
#include "FrameSequenceParseErrors.h"
|
||||
|
||||
class EnvelopeParserTest : public UnitTest {
|
||||
|
||||
public:
|
||||
EnvelopeParserTest() : UnitTest("Custom Envelope Parser Test") {}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
FrameSequenceParser parser;
|
||||
|
||||
beginTest ("No repeat");
|
||||
String input1 = "aaa"; // At this phase it doesn't matter if it contains numbers or not
|
||||
auto result1 = parser.findSegment(input1);
|
||||
expect(result1.repeatStartIndex == SegmentIndexes::NONE);
|
||||
expect(result1.repeatEndIndex == SegmentIndexes::NONE);
|
||||
expect(result1.releaseBlockIndex == SegmentIndexes::NONE);
|
||||
|
||||
beginTest ("With repeat, no release");
|
||||
String input2 = "aa[bbb]";
|
||||
auto result2 = parser.findSegment(input2);
|
||||
expect(result2.repeatStartIndex == 3);
|
||||
expect(result2.repeatEndIndex == 6);
|
||||
expect(result2.releaseBlockIndex == SegmentIndexes::NONE);
|
||||
|
||||
beginTest ("Repeat segment starts from the top");
|
||||
String input3 = "[aaa]";
|
||||
auto result3 = parser.findSegment(input3);
|
||||
expect(result3.repeatStartIndex == 1);
|
||||
expect(result3.repeatEndIndex == 4);
|
||||
expect(result3.releaseBlockIndex == SegmentIndexes::NONE);
|
||||
|
||||
beginTest ("No repeat, with release");
|
||||
String input4 = "aaa|bbbb";
|
||||
auto result4 = parser.findSegment(input4);
|
||||
expect(result4.repeatStartIndex == SegmentIndexes::NONE);
|
||||
expect(result4.repeatEndIndex == 3); // It doesn't repeat, but it has to keep the last index of pre-release segment
|
||||
expect(result4.releaseBlockIndex == 4);
|
||||
|
||||
beginTest ("Release segment without pre-release segment");
|
||||
String input5 = "|bbbb";
|
||||
auto result5 = parser.findSegment(input5);
|
||||
expect(result5.repeatStartIndex == SegmentIndexes::NONE);
|
||||
expect(result5.repeatEndIndex == 0); // This results in an immediate transition to Release Phase
|
||||
expect(result5.releaseBlockIndex == 1);
|
||||
|
||||
beginTest ("Repeat and release (no pre-repeat)");
|
||||
String input6 = "[aaa]|bbbb";
|
||||
auto result6 = parser.findSegment(input6);
|
||||
expect(result6.repeatStartIndex == 1);
|
||||
expect(result6.repeatEndIndex == 4);
|
||||
expect(result6.releaseBlockIndex == 6);
|
||||
|
||||
beginTest ("Repeat and release (with pre-repeat)");
|
||||
String input7 = "aaa[bbb]|cccc";
|
||||
auto result7 = parser.findSegment(input7);
|
||||
expect(result7.repeatStartIndex == 4);
|
||||
expect(result7.repeatEndIndex == 7);
|
||||
expect(result7.releaseBlockIndex == 9);
|
||||
|
||||
beginTest ("Empty repeat section");
|
||||
String input8 = "aaa[]|cccc";
|
||||
auto result8 = parser.findSegment(input8);
|
||||
expect(result8.repeatStartIndex == 4);
|
||||
expect(result8.repeatEndIndex == 4);
|
||||
expect(result8.releaseBlockIndex == 6);
|
||||
|
||||
beginTest ("Empty release section");
|
||||
String input9 = "aaa[bbb]|";
|
||||
auto result9 = parser.findSegment(input9);
|
||||
expect(result9.repeatStartIndex == 4);
|
||||
expect(result9.repeatEndIndex == 7);
|
||||
expect(result9.releaseBlockIndex == 9);
|
||||
|
||||
}
|
||||
};
|
@ -224,7 +224,7 @@ std::vector<int> FrameSequenceParser::parseSegment (const String& input,
|
||||
return retval;
|
||||
}
|
||||
|
||||
FrameSequenceParser::SegmentIndexes FrameSequenceParser::findSegment(const String& input) {
|
||||
SegmentIndexes FrameSequenceParser::findSegment(const String& input) {
|
||||
int releaseBlockIndex = -1;
|
||||
int repeatStartIndex = -1;
|
||||
int repeatEndIndex = -1;
|
||||
@ -359,112 +359,11 @@ FrameSequence FrameSequenceParser::parse (const String& input,
|
||||
//
|
||||
// Overall structure
|
||||
//
|
||||
SegmentIndexes si = findSegment(trimmed);
|
||||
|
||||
int releaseBlockIndex = -1;
|
||||
int repeatStartIndex = -1;
|
||||
int repeatEndIndex = -1;
|
||||
int openBracketCount = 0;
|
||||
int closeBracketCount = 0;
|
||||
|
||||
// loop by character
|
||||
for (int i = 0; i < trimmed.length(); i++)
|
||||
{
|
||||
if (trimmed[i] == '|') // found "|":
|
||||
{
|
||||
if (releaseBlockIndex >= 0)
|
||||
{
|
||||
// if releaseBlockIndex is already determined: Duplication Error
|
||||
*error = kParseErrorDuplicatedReleaseDelimiter;
|
||||
return fs;
|
||||
}
|
||||
|
||||
// if(repeatStartIndex >= 0) {
|
||||
// // if appeard before "[" or "]": Repetition After Release Error
|
||||
// throw new FrameSequenceParseException(TRANS("You cannot repeat in release phase"), true);
|
||||
// }
|
||||
// set releaseBlockIndex
|
||||
releaseBlockIndex = i + 1;
|
||||
|
||||
if (repeatEndIndex < 0)
|
||||
{
|
||||
// if "]" is omitted: Also set repeatEndIndex
|
||||
repeatEndIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (trimmed[i] == '[') /// found "[":
|
||||
{
|
||||
openBracketCount++;
|
||||
|
||||
if (openBracketCount > 1)
|
||||
{
|
||||
// Duplication Error
|
||||
*error = kParseErrorDuplicatedOpenBracket;
|
||||
return fs;
|
||||
}
|
||||
|
||||
if (releaseBlockIndex >= 0)
|
||||
{
|
||||
// if repeat end is already defined: Repetition After Release Error
|
||||
*error = kParseErrorRepeatingInReleaseBlock;
|
||||
return fs;
|
||||
}
|
||||
|
||||
if (repeatEndIndex >= 0)
|
||||
{
|
||||
// if repeat end is already defined: Repetition After Release Error
|
||||
*error = kParseErrorDuplicatedOpenBracket;
|
||||
return fs;
|
||||
}
|
||||
|
||||
// set repeatStartIndex
|
||||
repeatStartIndex = i + 1;
|
||||
}
|
||||
|
||||
if (trimmed[i] == ']') // found "]":
|
||||
{
|
||||
closeBracketCount++;
|
||||
|
||||
if (closeBracketCount > 1)
|
||||
{
|
||||
// Duplication Error
|
||||
*error = kParseErrorDuplicatedCloseBracket;
|
||||
return fs;
|
||||
}
|
||||
|
||||
if (repeatStartIndex < 0)
|
||||
{
|
||||
// if repeatStartIndex hasn't set: Syntax Error
|
||||
*error = kParseErrorUnmatchingCloseBracket;
|
||||
return fs;
|
||||
}
|
||||
|
||||
if (releaseBlockIndex >= 0)
|
||||
{
|
||||
// if repeat end is already defined: Repetition After Release Error
|
||||
*error = kParseErrorRepeatingInReleaseBlock;
|
||||
return fs;
|
||||
}
|
||||
|
||||
repeatEndIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// if (releaseBlockIndex < 0) { // "|" didn't explicitly specified
|
||||
// releaseBlockIndex = trimmed.length();
|
||||
// }
|
||||
|
||||
if (openBracketCount != closeBracketCount)
|
||||
{
|
||||
*error = kParseErrorUnmatchingBracketNumber;
|
||||
return fs;
|
||||
}
|
||||
|
||||
if (releaseBlockIndex - repeatEndIndex > 1)
|
||||
{
|
||||
// throw new FrameSequenceParseException(TRANS("Elements between repeat block and release block will be ignored"), false);
|
||||
// FiXME: non-fatal exceptionをどう扱うか
|
||||
}
|
||||
int releaseBlockIndex = si.releaseBlockIndex;
|
||||
int repeatStartIndex = si.repeatStartIndex;
|
||||
int repeatEndIndex = si.repeatEndIndex;
|
||||
|
||||
// Just for convenience
|
||||
bool hasRelease = (releaseBlockIndex >= 0);
|
||||
|
@ -13,6 +13,15 @@
|
||||
#include "FrameSequence.h"
|
||||
#include "FrameSequenceParseErrors.h"
|
||||
|
||||
struct SegmentIndexes {
|
||||
static const int NONE = -1;
|
||||
|
||||
int releaseBlockIndex = NONE;
|
||||
int repeatStartIndex = NONE;
|
||||
int repeatEndIndex = NONE;
|
||||
ParseError error;
|
||||
};
|
||||
|
||||
struct FrameSequenceParser
|
||||
{
|
||||
/*
|
||||
@ -23,15 +32,6 @@ struct FrameSequenceParser
|
||||
/*
|
||||
Semantically private (leave them open for unit testing)
|
||||
*/
|
||||
struct SegmentIndexes {
|
||||
const int NONE = -1;
|
||||
|
||||
int releaseBlockIndex = NONE;
|
||||
int repeatStartIndex = NONE;
|
||||
int repeatEndIndex = NONE;
|
||||
ParseError error;
|
||||
};
|
||||
|
||||
std::vector<int> parseSlope (const String& input,
|
||||
int minValue,
|
||||
int maxValue,
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "TriangleVoice.h"
|
||||
#include "NoiseVoice.h"
|
||||
#include "FrameSequenceParseErrors.h"
|
||||
#include "EnvelopeParserTest.h"
|
||||
|
||||
//==============================================================================
|
||||
Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
@ -114,7 +115,7 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
std::make_unique<AudioParameterBool> ("isPitchSequenceEnabled_raw", "Enabled", false),
|
||||
std::make_unique<AudioParameterBool> ("isDutySequenceEnabled_raw", "Enabled", false),
|
||||
std::make_unique<AudioParameterChoice> ("pitchSequenceMode_raw", "Mode", StringArray ({"Coarse", "Fine"}), 0)
|
||||
}
|
||||
}
|
||||
)
|
||||
, settingRefs (¶meters)
|
||||
#ifndef JucePlugin_PreferredChannelConfigurations
|
||||
@ -132,6 +133,12 @@ Magical8bitPlug2AudioProcessor::Magical8bitPlug2AudioProcessor()
|
||||
|
||||
setupVoice();
|
||||
synth.addSound (new GenericSound());
|
||||
|
||||
#if JUCE_DEBUG
|
||||
EnvelopeParserTest test;
|
||||
UnitTestRunner runner;
|
||||
runner.runAllTests();
|
||||
#endif
|
||||
}
|
||||
|
||||
Magical8bitPlug2AudioProcessor::~Magical8bitPlug2AudioProcessor()
|
||||
|
Loading…
Reference in New Issue
Block a user