Skip to content

Commit

Permalink
Merge pull request #12 from TheSlowGrowth/develop
Browse files Browse the repository at this point in the history
v0.2.1
  • Loading branch information
TheSlowGrowth authored Jul 4, 2016
2 parents 892bd22 + 8ab1e38 commit 351f8e0
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 30 deletions.
21 changes: 17 additions & 4 deletions Source/MainComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "MainComponent.h"
#include "ReportCreatorWindow.h"

MainComponent::MainComponent() : tuner(&deviceManager)
MainComponent::MainComponent() : tuner(&deviceManager), display(&tuner)
{
ScopedPointer<XmlElement> savedAudioState (getAppProperties().getUserSettings()
->getXmlValue ("audioDeviceState"));
Expand Down Expand Up @@ -82,6 +82,15 @@ MainComponent::MainComponent() : tuner(&deviceManager)

cycle = false;
creatingReport = false;

// for first-time starters, display a help message and the audio settings
if ((!getAppProperties().getUserSettings()->containsKey("hideWelcomeScreen"))
|| (getAppProperties().getUserSettings()->getIntValue("hideWelcomeScreen") != 1))
{
NativeMessageBox::showMessageBox(AlertWindow::AlertIconType::InfoIcon, "Welcome!", welcomeText);
showAudioSettings();
getAppProperties().getUserSettings()->setValue("hideWelcomeScreen", 1);
}
}

MainComponent::~MainComponent()
Expand Down Expand Up @@ -114,13 +123,14 @@ void MainComponent::resized()
display.setBounds(borderWidth,
regimeLabel.getBottom() + borderWidth,
getWidth() - 2 * borderWidth,
getHeight() - 2* borderWidth - audioSettings.getBottom());
getHeight() - 2* borderWidth - regimeLabel.getBottom());

}

void MainComponent::paint(Graphics& g)
{
g.setColour(Colours::lightgrey);
g.fillAll();
}


Expand Down Expand Up @@ -235,8 +245,9 @@ void MainComponent::showAudioSettings()
"9", "10", "11", "12", "13", "14", "15", "16"};
channelEdit.addItemList(StringArray(items, 16), 1);
channelEdit.addListener(this);
channelEdit.setSelectedId(getAppProperties().getUserSettings()->getIntValue("MIDIChannel"));
if (channelEdit.getSelectedId() == 0) // in case nothing is selected - select first entry
if (getAppProperties().getUserSettings()->containsKey("MIDIChannel"))
channelEdit.setSelectedId(getAppProperties().getUserSettings()->getIntValue("MIDIChannel"));
else
channelEdit.setSelectedId(1);
addAndMakeVisible(&channelEdit);

Expand Down Expand Up @@ -374,3 +385,5 @@ const char* MainComponent::resolutionsTexts[numResolutions] = {

const MainComponent::regime_t MainComponent::reportRange = {24, 96, 1};

const String MainComponent::welcomeText = String("Welcome to the VCO Tuner!") + newLine + newLine + "Please follow these steps to get running:" + newLine + "1) connect a MIDI-CV interface to your Computer" + newLine + "2) connect the CV output of the interface to your oscillators frequency input" + newLine + "3) Connect one of the oscillators basic wavaforms (sine, saw, triangle, pulse, etc.) directly to your soundcard." + newLine + newLine + "When you close this dialog, the audio settings panel will open. Please select your audio and midi device there." + newLine + newLine + "Have fun!" + newLine + newLine + "PS: If you find any bugs, please raise an issue on the github repository under https://github.com/TheSlowGrowth/VCOTuner. Thanks!";

2 changes: 2 additions & 0 deletions Source/MainComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class MainComponent: public Component,
bool cycle;
bool creatingReport;

static const String welcomeText;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

Expand Down
3 changes: 2 additions & 1 deletion Source/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ MainWindow::MainWindow()

setContentOwned (new MainComponent (), false);

restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos"));
if (getAppProperties().getUserSettings()->containsKey("mainWindowPos"))
restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos"));
setVisible(true);
}

Expand Down
2 changes: 2 additions & 0 deletions Source/ReportCreatorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ ReportCreatorWindow::ReportCreatorWindow(VCOTuner* t, Visualizer* v)
ReportCreatorWindow::~ReportCreatorWindow()
{
delete currentContentComponent;
if (tuner->isRunning())
tuner->toggleState();
}

void ReportCreatorWindow::next()
Expand Down
25 changes: 15 additions & 10 deletions Source/ReportDetailsEditorScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ ReportDetailsEditorScreen::ReportDetailsEditorScreen(VCOTuner* t, Visualizer* v,
addAndMakeVisible(&brandLabel);

brandEdit.setName("BrandEdit");
brandEdit.setText(getAppProperties().getUserSettings()->getValue("DUT-Brand"), dontSendNotification);
if (brandEdit.getText() == "")
if (getAppProperties().getUserSettings()->containsKey("DUT-Brand"))
brandEdit.setText(getAppProperties().getUserSettings()->getValue("DUT-Brand"), dontSendNotification);
else
brandEdit.setText(" - ", dontSendNotification);
addAndMakeVisible(&brandEdit);

Expand All @@ -45,8 +46,9 @@ ReportDetailsEditorScreen::ReportDetailsEditorScreen(VCOTuner* t, Visualizer* v,
addAndMakeVisible(&deviceLabel);

deviceEdit.setName("deviceEdit");
deviceEdit.setText(getAppProperties().getUserSettings()->getValue("DUT-Device"), dontSendNotification);
if (deviceEdit.getText() == "")
if (getAppProperties().getUserSettings()->containsKey("DUT-Device"))
deviceEdit.setText(getAppProperties().getUserSettings()->getValue("DUT-Device"), dontSendNotification);
else
deviceEdit.setText(" - ", dontSendNotification);
addAndMakeVisible(&deviceEdit);

Expand All @@ -56,8 +58,9 @@ ReportDetailsEditorScreen::ReportDetailsEditorScreen(VCOTuner* t, Visualizer* v,
addAndMakeVisible(&interfaceBrandLabel);

interfaceBrandEdit.setName("InterfaceBrandEdit");
interfaceBrandEdit.setText(getAppProperties().getUserSettings()->getValue("Interface-Brand"), dontSendNotification);
if (interfaceBrandEdit.getText() == "")
if (getAppProperties().getUserSettings()->containsKey("Interface-Brand"))
interfaceBrandEdit.setText(getAppProperties().getUserSettings()->getValue("Interface-Brand"), dontSendNotification);
else
interfaceBrandEdit.setText(" - ", dontSendNotification);
addAndMakeVisible(&interfaceBrandEdit);

Expand All @@ -67,8 +70,9 @@ ReportDetailsEditorScreen::ReportDetailsEditorScreen(VCOTuner* t, Visualizer* v,
addAndMakeVisible(&interfaceLabel);

interfaceEdit.setName("InterfaceEdit");
interfaceEdit.setText(getAppProperties().getUserSettings()->getValue("Interface-Device"), dontSendNotification);
if (interfaceEdit.getText() == "")
if (getAppProperties().getUserSettings()->containsKey("Interface-Device"))
interfaceEdit.setText(getAppProperties().getUserSettings()->getValue("Interface-Device"), dontSendNotification);
else
interfaceEdit.setText(" - ", dontSendNotification);
addAndMakeVisible(&interfaceEdit);

Expand All @@ -80,8 +84,9 @@ ReportDetailsEditorScreen::ReportDetailsEditorScreen(VCOTuner* t, Visualizer* v,
notesEdit.setName("NotesEdit");
notesEdit.setMultiLine(true);
notesEdit.setReturnKeyStartsNewLine(true);
notesEdit.setText(getAppProperties().getUserSettings()->getValue("Notes"), dontSendNotification);
if (notesEdit.getText() == "")
if (getAppProperties().getUserSettings()->containsKey("Notes"))
notesEdit.setText(getAppProperties().getUserSettings()->getValue("Notes"), dontSendNotification);
else
notesEdit.setText(" - ", dontSendNotification);
addAndMakeVisible(&notesEdit);

Expand Down
3 changes: 3 additions & 0 deletions Source/VCOTuner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ VCOTuner::~VCOTuner()
{
stopTimer();

if (currentlyPlayingMidiNote >= 0)
trySendMidiNoteOff(currentlyPlayingMidiNote);

if (midiOut != nullptr)
{
delete midiOut;
Expand Down
1 change: 1 addition & 0 deletions Source/VCOTuner.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class VCOTuner: public ChangeListener,

double getCurrentSampleRate() { return sampleRate; }
double getReferenceFrequency() { return referenceFrequency; }
int getReferencePitch() const { return referencePitch; }

String getStatusString()const;

Expand Down
116 changes: 102 additions & 14 deletions Source/Visualizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
#include "Visualizer.h"


Visualizer::Visualizer()
Visualizer::Visualizer(VCOTuner* t)
{

tuner = t;
}

Visualizer::~Visualizer()
Expand Down Expand Up @@ -58,6 +58,17 @@ void Visualizer::paintWithFixedScaling(Graphics& g, int width, int height, doubl
return;
}

// fill background
//g.setColour(Colours::lightgrey);
//g.fillAll();

const int bottomBarHeight = 20;

int imageHeight = height - bottomBarHeight;

// prepare coordinate transformation (flipping the y axis)
heightForFlipping = (float) imageHeight;

const float sidebarWidth = 75;
double columnWidth = (double) (width - sidebarWidth) / (double) measurements.size();
const double allowedPitchOffset = 0.02; // 5 cents allowed
Expand All @@ -70,17 +81,17 @@ void Visualizer::paintWithFixedScaling(Graphics& g, int width, int height, doubl
if (max < min)
return;

double vertScaling = (double) height / (max - min);
double vertScaling = (double) imageHeight / (max - min);

// draw maximum "in-tune" pitch offset and center line
g.setColour(Colours::grey);
const float dashLengths[] = {4, 4};
double position = (allowedPitchOffset - min) * vertScaling;
g.drawDashedLine(Line<float>(sidebarWidth, (float) position, (float) width, (float) position), dashLengths, 2);
g.drawDashedLine(Line<float>(sidebarWidth, yFlip((float) position), (float) width, yFlip((float) position)), dashLengths, 2);
position = (-allowedPitchOffset - min) * vertScaling;
g.drawDashedLine(Line<float>(sidebarWidth, (float) position, (float) width, (float) position), dashLengths, 2);
g.drawDashedLine(Line<float>(sidebarWidth, yFlip((float) position), (float) width, yFlip((float) position)), dashLengths, 2);
position = (- min) * vertScaling;
g.drawLine(sidebarWidth, (float) position, (float) width, (float) position);
g.drawLine(sidebarWidth, yFlip((float) position), (float) width, yFlip((float) position));

// draw scales
g.setColour(Colours::grey);
Expand All @@ -89,7 +100,7 @@ void Visualizer::paintWithFixedScaling(Graphics& g, int width, int height, doubl
double lineInterval = allowedIntervals[0];
int currentIntervalIndex = 0;

int numLinesAllowed = height / 30;
int numLinesAllowed = imageHeight / 30;
while (((max - min) / lineInterval) > numLinesAllowed)
{
lineInterval = allowedIntervals[++currentIntervalIndex];
Expand All @@ -98,7 +109,7 @@ void Visualizer::paintWithFixedScaling(Graphics& g, int width, int height, doubl
}
bool useSemitoneTexts = lineInterval >= 1.0;

int numPosLines = (int) trunc(max/lineInterval) + 1;
int numPosLines = (int) trunc(max/lineInterval);
int numNegLines = (int) trunc(-min/lineInterval);
for (double y = numPosLines; y > -numNegLines; y--)
{
Expand All @@ -109,14 +120,14 @@ void Visualizer::paintWithFixedScaling(Graphics& g, int width, int height, doubl
String lineText = numberString;
if (!useSemitoneTexts)
lineText += " cents";
g.drawText(lineText, 0, (int) position - 8, (int) left-4, 16, Justification::centredRight);
g.drawText(lineText, 0, (int) yFlip(position + g.getCurrentFont().getHeight()/2), (int) left-4, g.getCurrentFont().getHeight(), Justification::centredRight);

// don't overwrite maximum "in-tune" lines
if (y*lineInterval == allowedPitchOffset || y*lineInterval == -allowedPitchOffset)
continue;

const float dashLengths[] = {4, 20};
g.drawDashedLine(Line<float>((float) left, (float) position, (float) width, (float) position), dashLengths, 2);
g.drawDashedLine(Line<float>((float) left, yFlip((float) position), (float) width, yFlip((float) position)), dashLengths, 2);

}

Expand All @@ -130,14 +141,86 @@ void Visualizer::paintWithFixedScaling(Graphics& g, int width, int height, doubl
float minPosition = (float) ((measurements[i].pitchOffset - measurements[i].pitchDeviation - min) * vertScaling);

g.setColour(Colours::springgreen.withAlpha(0.4f));
g.fillRect(left, minPosition, (float) columnWidth, maxPosition - minPosition);
g.fillRect(left, yFlip(maxPosition), (float) columnWidth, maxPosition - minPosition);

// draw average value
float position = (float) ((measurements[i].pitchOffset - min) * vertScaling);


g.setColour(Colours::green);
g.drawLine(left, position, left + (float) columnWidth, position);
g.drawLine(left, yFlip(position), left + (float) columnWidth, yFlip(position));
}

// draw the X-Axis label
g.setColour(Colours::black);
g.drawText("MIDI note", 0, imageHeight, sidebarWidth - 10, bottomBarHeight, Justification::centredRight);

// draw the corresponding note values to the X axis
const int numPitchTextIntervals = 5;
const int pitchTextIntervals[numPitchTextIntervals] = {1, 2, 5, 10, 20};
int currentPitchTextIntervalIndex = 0;
while (g.getCurrentFont().getStringWidth("123.") > pitchTextIntervals[currentPitchTextIntervalIndex] * columnWidth)
{
currentPitchTextIntervalIndex++;
if (currentPitchTextIntervalIndex >= numPitchTextIntervals)
break;
}
int pitchTextInterval = pitchTextIntervals[currentPitchTextIntervalIndex];
int startLine = 0;
int endLine = measurements.size() - 1;
while (measurements[startLine].midiPitch % pitchTextInterval != 0)
{
startLine++;
if (startLine >= measurements.size())
return;
}
while (measurements[endLine].midiPitch % pitchTextInterval != 0)
{
endLine--;
if (endLine < 0 || endLine < startLine)
return;
}

for (int i = startLine; i <= endLine; i += pitchTextInterval)
{
g.setColour(Colours::black);
float textWidth = g.getCurrentFont().getStringWidth(String(measurements[i].midiPitch));
float left = sidebarWidth + i * columnWidth;
float x = left + columnWidth/2 - textWidth/2;
float y = imageHeight;
g.drawText(String(measurements[i].midiPitch), x, y, textWidth, bottomBarHeight, Justification::centred);

// the line for the reference pitch will be drawn later
if (measurements[i].midiPitch == tuner->getReferencePitch())
continue;

// also draw dim vertical lines for the larger devisions or if the columns get very narrow
if (pitchTextInterval >= 2)
{
g.setColour(Colours::blue.withAlpha(0.05f));
g.fillRect(Rectangle<float>(left, 0, columnWidth, imageHeight));
}
if (pitchTextInterval == 1 && columnWidth < g.getCurrentFont().getStringWidth("123."))
{
if (i % 2 == 0)
{
g.setColour(Colours::blue.withAlpha(0.05f));
g.fillRect(Rectangle<float>(left, 0, columnWidth, imageHeight));
}
}
}

// draw a blue indicator for the reference pitch (if included in the measurements)
if (measurements[0].midiPitch < tuner->getReferencePitch()
&& measurements.getLast().midiPitch > tuner->getReferencePitch())
{
for (int i = 0; i < measurements.size(); i++)
{
if (measurements[i].midiPitch == tuner->getReferencePitch())
{
float left = sidebarWidth + i * columnWidth;
g.setColour(Colours::blue.withAlpha(0.15f));
g.fillRect(Rectangle<float>(left, 0, columnWidth, imageHeight));
}
}
}
}

Expand All @@ -146,6 +229,11 @@ void Visualizer::paint(Graphics& g)
paint(g, getWidth(), getHeight());
}

float Visualizer::yFlip(float y)
{
return heightForFlipping - y;
}

void Visualizer::newMeasurementReady(const VCOTuner::measurement_t& m)
{
bool found = false;
Expand Down
7 changes: 6 additions & 1 deletion Source/Visualizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Visualizer: public Component,
public VCOTuner::Listener
{
public:
Visualizer();
Visualizer(VCOTuner* t);
~Visualizer();

void paintWithFixedScaling(Graphics& g, int width, int height, double min, double max);
Expand All @@ -30,6 +30,11 @@ class Visualizer: public Component,
private:
/** holds the list of completed measurements */
Array<VCOTuner::measurement_t> measurements;

float heightForFlipping;
float yFlip(float y);

VCOTuner* tuner;
};


Expand Down

0 comments on commit 351f8e0

Please sign in to comment.