2
0
Fork 0

Add record button into GUI, halve output level.

This commit is contained in:
bruce 2014-11-01 22:26:48 +09:00
parent d9af5c2d75
commit f06c7147c7
6 changed files with 86 additions and 11 deletions

View file

@ -26,6 +26,9 @@
//[MiscUserDefs] You can add your own user definitions and misc code here... //[MiscUserDefs] You can add your own user definitions and misc code here...
void PluginGui::updateFromParameters() void PluginGui::updateFromParameters()
{ {
emulatorSlider->setValue(processor->getEnumParameter("Emulator"), juce::NotificationType::dontSendNotification);
setRecordButtonState(processor->isRecording());
sineImageButton->setToggleState(false, false); sineImageButton->setToggleState(false, false);
halfsineImageButton->setToggleState(false, false); halfsineImageButton->setToggleState(false, false);
abssineImageButton->setToggleState(false, false); abssineImageButton->setToggleState(false, false);
@ -838,6 +841,11 @@ PluginGui::PluginGui (JuceOplvstiAudioProcessor* ownerFilter)
emulatorLabel2->setColour (TextEditor::textColourId, Colours::black); emulatorLabel2->setColour (TextEditor::textColourId, Colours::black);
emulatorLabel2->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); emulatorLabel2->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
addAndMakeVisible (recordButton = new ToggleButton ("record button"));
recordButton->setButtonText (TRANS("Record to DRO"));
recordButton->addListener (this);
recordButton->setColour (ToggleButton::textColourId, Colour (0xff007f00));
//[UserPreSize] //[UserPreSize]
frequencyComboBox->setColour (ComboBox::textColourId, Colour (COLOUR_MID)); frequencyComboBox->setColour (ComboBox::textColourId, Colour (COLOUR_MID));
@ -941,6 +949,7 @@ PluginGui::PluginGui (JuceOplvstiAudioProcessor* ownerFilter)
logsawImageButton2->setClickingTogglesState(true); logsawImageButton2->setClickingTogglesState(true);
logsawImageButton2->setRepaintsOnMouseActivity(false); logsawImageButton2->setRepaintsOnMouseActivity(false);
recordButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
tremoloButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID)); tremoloButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
vibratoButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID)); vibratoButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
keyscaleEnvButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID)); keyscaleEnvButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
@ -1060,6 +1069,7 @@ PluginGui::~PluginGui()
emulatorSlider = nullptr; emulatorSlider = nullptr;
emulatorLabel = nullptr; emulatorLabel = nullptr;
emulatorLabel2 = nullptr; emulatorLabel2 = nullptr;
recordButton = nullptr;
//[Destructor]. You can add your own custom destruction code here.. //[Destructor]. You can add your own custom destruction code here..
@ -1157,9 +1167,10 @@ void PluginGui::resized()
keyscaleAttenuationComboBox->setBounds (264, 144, 72, 24); keyscaleAttenuationComboBox->setBounds (264, 144, 72, 24);
groupComponent4->setBounds (16, 856, 408, 64); groupComponent4->setBounds (16, 856, 408, 64);
groupComponent5->setBounds (16, 8, 408, 48); groupComponent5->setBounds (16, 8, 408, 48);
emulatorSlider->setBounds (208, 24, 32, 24); emulatorSlider->setBounds (112, 24, 32, 24);
emulatorLabel->setBounds (128, 24, 72, 24); emulatorLabel->setBounds (32, 24, 72, 24);
emulatorLabel2->setBounds (248, 24, 72, 24); emulatorLabel2->setBounds (152, 24, 72, 24);
recordButton->setBounds (272, 24, 128, 24);
//[UserResized] Add your own custom resize handling here.. //[UserResized] Add your own custom resize handling here..
for (unsigned int i = 0; i < channels.size(); ++i) for (unsigned int i = 0; i < channels.size(); ++i)
channels[i]->setBounds(32+44*i+4, 880+4, 16, 16); channels[i]->setBounds(32+44*i+4, 880+4, 16, 16);
@ -1322,12 +1333,24 @@ void PluginGui::sliderValueChanged (Slider* sliderThatWasMoved)
//[/UsersliderValueChanged_Post] //[/UsersliderValueChanged_Post]
} }
void PluginGui::setRecordButtonState(bool recording) {
if (recording) {
recordButton->setColour(TextButton::buttonColourId, Colour(COLOUR_RECORDING));
recordButton->setButtonText("Recording..");
recordButton->setColour(ToggleButton::textColourId, Colour(COLOUR_RECORDING));
} else {
recordButton->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
recordButton->setButtonText("Record to DRO");
recordButton->setColour(ToggleButton::textColourId, Colour(COLOUR_MID));
}
}
void PluginGui::buttonClicked (Button* buttonThatWasClicked) void PluginGui::buttonClicked (Button* buttonThatWasClicked)
{ {
//[UserbuttonClicked_Pre] //[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre] //[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == sineImageButton) if (buttonThatWasClicked == sineImageButton)
{ {
//[UserButtonCode_sineImageButton] -- add your button handler code here.. //[UserButtonCode_sineImageButton] -- add your button handler code here..
processor->setEnumParameter("Modulator Wave", 0); processor->setEnumParameter("Modulator Wave", 0);
@ -1471,6 +1494,33 @@ void PluginGui::buttonClicked (Button* buttonThatWasClicked)
processor->setEnumParameter("Carrier Wave", 7); processor->setEnumParameter("Carrier Wave", 7);
//[/UserButtonCode_logsawImageButton2] //[/UserButtonCode_logsawImageButton2]
} }
else if (buttonThatWasClicked == recordButton)
{
//[UserButtonCode_recordButton] -- add your button handler code here..
recordButton->setToggleState(false, false);
if (!processor->isRecording()) {
WildcardFileFilter wildcardFilter ("*.dro", String::empty, "DRO files");
FileBrowserComponent browser (FileBrowserComponent::saveMode,
File::nonexistent,
&wildcardFilter,
nullptr);
FileChooserDialogBox dialogBox ("Record to",
"Specify DRO output file",
browser,
true,
Colours::darkgreen);
if (dialogBox.show())
{
File selectedFile = browser.getSelectedFile(0);
processor->startRecording(&selectedFile);
setRecordButtonState(true);
}
} else {
setRecordButtonState(false);
processor->stopRecording();
}
//[/UserButtonCode_recordButton]
}
//[UserbuttonClicked_Post] //[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post] //[/UserbuttonClicked_Post]
@ -1921,21 +1971,25 @@ BEGIN_JUCER_METADATA
virtualName="" explicitFocusOrder="0" pos="16 8 408 48" outlinecol="ff007f00" virtualName="" explicitFocusOrder="0" pos="16 8 408 48" outlinecol="ff007f00"
textcol="ff007f00" title="Emulator" textpos="33"/> textcol="ff007f00" title="Emulator" textpos="33"/>
<SLIDER name="emulator slider" id="88ec3755c4760ed9" memberName="emulatorSlider" <SLIDER name="emulator slider" id="88ec3755c4760ed9" memberName="emulatorSlider"
virtualName="" explicitFocusOrder="0" pos="208 24 32 24" thumbcol="ff00af00" virtualName="" explicitFocusOrder="0" pos="112 24 32 24" thumbcol="ff00af00"
trackcol="7f007f00" textboxtext="ff007f00" textboxbkgd="ff000000" trackcol="7f007f00" textboxtext="ff007f00" textboxbkgd="ff000000"
textboxhighlight="ff00af00" min="0" max="1" int="1" style="LinearHorizontal" textboxhighlight="ff00af00" min="0" max="1" int="1" style="LinearHorizontal"
textBoxPos="NoTextBox" textBoxEditable="0" textBoxWidth="44" textBoxPos="NoTextBox" textBoxEditable="0" textBoxWidth="44"
textBoxHeight="20" skewFactor="1"/> textBoxHeight="20" skewFactor="1"/>
<LABEL name="emulator label" id="22c2c30d0f337081" memberName="emulatorLabel" <LABEL name="emulator label" id="22c2c30d0f337081" memberName="emulatorLabel"
virtualName="" explicitFocusOrder="0" pos="128 24 72 24" textCol="ff007f00" virtualName="" explicitFocusOrder="0" pos="32 24 72 24" textCol="ff007f00"
edTextCol="ff000000" edBkgCol="0" labelText="DOSBox" editableSingleClick="0" edTextCol="ff000000" edBkgCol="0" labelText="DOSBox" editableSingleClick="0"
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
fontsize="15" bold="0" italic="0" justification="34"/> fontsize="15" bold="0" italic="0" justification="34"/>
<LABEL name="emulator label" id="4f8869b5724c0195" memberName="emulatorLabel2" <LABEL name="emulator label" id="4f8869b5724c0195" memberName="emulatorLabel2"
virtualName="" explicitFocusOrder="0" pos="248 24 72 24" textCol="ff007f00" virtualName="" explicitFocusOrder="0" pos="152 24 72 24" textCol="ff007f00"
edTextCol="ff000000" edBkgCol="0" labelText="ZDoom" editableSingleClick="0" edTextCol="ff000000" edBkgCol="0" labelText="ZDoom" editableSingleClick="0"
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
fontsize="15" bold="0" italic="0" justification="33"/> fontsize="15" bold="0" italic="0" justification="33"/>
<TOGGLEBUTTON name="record button" id="880010ee79039cbe" memberName="recordButton"
virtualName="" explicitFocusOrder="0" pos="272 24 128 24" txtcol="ff007f00"
buttonText="Record to DRO" connectedEdges="0" needsCallback="1"
radioGroupId="0" state="0"/>
</JUCER_COMPONENT> </JUCER_COMPONENT>
END_JUCER_METADATA END_JUCER_METADATA

View file

@ -56,6 +56,7 @@ public:
void fileDragExit (const StringArray& files); void fileDragExit (const StringArray& files);
void filesDropped (const StringArray& files, int x, int y); void filesDropped (const StringArray& files, int x, int y);
void timerCallback(); void timerCallback();
void setRecordButtonState(bool recording);
//[/UserMethods] //[/UserMethods]
void paint (Graphics& g); void paint (Graphics& g);
@ -90,6 +91,7 @@ public:
private: private:
//[UserVariables] -- You can add your own custom variables in this section. //[UserVariables] -- You can add your own custom variables in this section.
static const uint32 COLOUR_MID = 0xff007f00; static const uint32 COLOUR_MID = 0xff007f00;
static const uint32 COLOUR_RECORDING = 0xffff0000;
JuceOplvstiAudioProcessor* processor; JuceOplvstiAudioProcessor* processor;
std::array<ScopedPointer<ImageButton>, Hiopl::CHANNELS> channels; std::array<ScopedPointer<ImageButton>, Hiopl::CHANNELS> channels;
//[/UserVariables] //[/UserVariables]
@ -175,6 +177,7 @@ private:
ScopedPointer<Slider> emulatorSlider; ScopedPointer<Slider> emulatorSlider;
ScopedPointer<Label> emulatorLabel; ScopedPointer<Label> emulatorLabel;
ScopedPointer<Label> emulatorLabel2; ScopedPointer<Label> emulatorLabel2;
ScopedPointer<ToggleButton> recordButton;
//============================================================================== //==============================================================================

View file

@ -16,6 +16,8 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
Opl->SetSampleRate(44100); Opl->SetSampleRate(44100);
Opl->EnableWaveformControl(); Opl->EnableWaveformControl();
recordingFile = NULL;
// Initialize parameters // Initialize parameters
const String waveforms[] = {"Sine", "Half Sine", "Abs Sine", "Quarter Sine", "Alternating Sine", "Camel Sine", "Square", "Logarithmic Sawtooth"}; const String waveforms[] = {"Sine", "Half Sine", "Abs Sine", "Quarter Sine", "Alternating Sine", "Camel Sine", "Square", "Logarithmic Sawtooth"};
@ -134,6 +136,18 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
available_channels.push_back(i); available_channels.push_back(i);
} }
bool JuceOplvstiAudioProcessor::isRecording() {
return NULL != recordingFile;
}
void JuceOplvstiAudioProcessor::startRecording(File *outputFile) {
recordingFile = outputFile;
}
void JuceOplvstiAudioProcessor::stopRecording() {
recordingFile = NULL;
}
void JuceOplvstiAudioProcessor::initPrograms() void JuceOplvstiAudioProcessor::initPrograms()
{ {
// these ones from the Syndicate in-game music // these ones from the Syndicate in-game music

View file

@ -17,8 +17,6 @@
//============================================================================== //==============================================================================
/**
*/
class JuceOplvstiAudioProcessor : public AudioProcessor class JuceOplvstiAudioProcessor : public AudioProcessor
{ {
public: public:
@ -28,6 +26,10 @@ public:
void applyPitchBend(); void applyPitchBend();
~JuceOplvstiAudioProcessor(); ~JuceOplvstiAudioProcessor();
bool isRecording();
void startRecording(File *outputFile);
void stopRecording();
//============================================================================== //==============================================================================
void prepareToPlay (double sampleRate, int samplesPerBlock); void prepareToPlay (double sampleRate, int samplesPerBlock);
void releaseResources(); void releaseResources();
@ -96,6 +98,7 @@ private:
std::deque<int> available_channels; // most recently freed at end std::deque<int> available_channels; // most recently freed at end
std::deque<int> used_channels; // most recently used at end std::deque<int> used_channels; // most recently used at end
float currentScaledBend; float currentScaledBend;
File *recordingFile;
//============================================================================== //==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceOplvstiAudioProcessor) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceOplvstiAudioProcessor)

View file

@ -1,7 +1,7 @@
#include "Hiopl.h" #include "Hiopl.h"
#include <assert.h> #include <assert.h>
#include "../JuceLibraryCode/JuceHeader.h" #include "JuceHeader.h"
// A wrapper around the DOSBox and ZDoom OPL emulators. // A wrapper around the DOSBox and ZDoom OPL emulators.
@ -50,7 +50,7 @@ void Hiopl::Generate(int length, float* buffer) {
adlib->Generate(length, buf32); adlib->Generate(length, buf32);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
// The magic divisor is tuned to match to ZDoom output amplitude. // The magic divisor is tuned to match to ZDoom output amplitude.
buffer[i] = (float)(buf32[i])/4100.0f; buffer[i] = (float)(buf32[i])/8200.0f;
} }
delete buf32; delete buf32;
} else if (ZDOOM == emulator) { } else if (ZDOOM == emulator) {

View file

@ -633,6 +633,7 @@ void OPL3::Update(float *output, int numsamples) {
output[0] += float(channelOutput); output[0] += float(channelOutput);
} }
} }
output[0] /= 2.0f; // scale output down to avoid clipping
// Advances the OPL3-wide vibrato index, which is used by // Advances the OPL3-wide vibrato index, which is used by
// PhaseGenerator.getPhase() in each Operator. // PhaseGenerator.getPhase() in each Operator.