AfarasView::AfarasView(QWidget *parent, Qt::WFlags flags) : KXmlGuiWindow(parent, flags), recorder(0), currentIndex(0) { KGlobal::locale()->insertCatalog("simonlib"); ui.setupUi(this); connect(ui.pbStartReview, SIGNAL(clicked()), this, SLOT(start())); connect(ui.pbBlacklistSample, SIGNAL(toggled(bool)), this, SLOT(blackListSample(bool))); connect(ui.pbPreviousSample, SIGNAL(clicked()), this, SLOT(previousSample())); connect(ui.pbNextSample, SIGNAL(clicked()), this, SLOT(nextSample())); connect(ui.pbBack, SIGNAL(clicked()), this, SLOT(stop())); connect(ui.urInputPrompts, SIGNAL(textChanged(QString)), this, SLOT(inputFilesChanged())); connect(ui.urPathPrefix, SIGNAL(textChanged(QString)), this, SLOT(inputFilesChanged())); connect(ui.urOutputBlacklist, SIGNAL(textChanged(QString)), this, SLOT(inputFilesChanged())); ui.wgRecording->setLayout(new QVBoxLayout()); KStandardAction::quit(this, SLOT(close()), actionCollection()); KStandardAction::preferences(this, SLOT(showConfig()), actionCollection()); setupGUI(); }
void MainContentComponent::filesDropped(const StringArray& filePaths, int x, int y) { x; y; int succeeded = 0; for (int i = 0; i < filePaths.size(); ++i) { String filePath = filePaths[i]; unique_ptr<Sound> sound(new Sound(filePath)); if (Sound::readBufferFromAudioFile(&formatManager, filePath, sound->getBufferPtr())) { const ScopedLock fl(soundListLock); int soundId = soundIdNext++; idToSound.emplace(soundId, std::move(sound)); ++succeeded; } } if (succeeded > 0) { inputFilesChanged(dontSendNotification); } if (succeeded < filePaths.size()) { AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Invalid file(s)", "One or more files failed to load."); } }
void MainContentComponent::buttonClicked (Button* buttonThatWasClicked) { //[UserbuttonClicked_Pre] //[/UserbuttonClicked_Pre] if (buttonThatWasClicked == convButton) { //[UserButtonCode_convButton] -- add your button handler code here.. const ScopedLock fl(soundListLock); setPlayheadUiEnabled(false); bool convValid = true; float q; float s; double nfft; { const ScopedLock pl(paramLock); q = qParam; s = sParam; nfft = static_cast<double>(nfftParam); } int fftInputLen = static_cast<int>(std::pow(2.0, nfft)); int fftOutputLen = fftInputLen / 2 + 1; int numChannels = 1; unordered_set<int> includedSounds; int maxChannels = 0; float pSum = 0.0f; float rSum = 0.0f; for (const auto& iter : idToSound) { int id = iter.first; Sound* sound = iter.second.get(); int numChannels = sound->getBufferNumChannels(); if (sound->isIncluded() && numChannels > 0) { maxChannels = numChannels > maxChannels ? numChannels : maxChannels; includedSounds.emplace(id); pSum += static_cast<float>(sound->getPValue()); rSum += static_cast<float>(sound->getRValue()); } } float n = static_cast<float>(includedSounds.size()); float pScale = n * q / pSum; float rScale = n * s / rSum; if (maxChannels == 0) { return; } kiss_fftr_state* fftInverseState = kiss_fftr_alloc(fftInputLen, 1, nullptr, nullptr); kiss_fft_cpx* CONV = static_cast<kiss_fft_cpx*>(calloc(fftOutputLen * maxChannels, sizeof(kiss_fft_cpx))); conv.setSize(maxChannels, fftInputLen); float max = -1.0f; // convolve for (int convChannel = 0; convChannel < maxChannels; ++convChannel) { kiss_fft_cpx* CONVCHANNEL = CONV + (convChannel * fftOutputLen); bool isFirstSound = true; for (const auto& id : includedSounds) { Sound* sound = idToSound[id].get(); jassert(sound != nullptr); float p = pScale * static_cast<float>(sound->getPValue()); float r = rScale * static_cast<float>(sound->getRValue()); int soundNumChannels = sound->getBufferNumChannels(); int soundNumSamples = sound->getBufferNumSamples(); int soundChannel = convChannel >= soundNumChannels ? soundNumChannels - 1 : convChannel; const kiss_fft_cpx* SOUNDCHANNEL = sound->getSpectra(fftInputLen, soundChannel); for (int i = 0; i < fftOutputLen; ++i) { float xr = SOUNDCHANNEL[i].r; float xi = SOUNDCHANNEL[i].i; float xMag = sqrtf((xr * xr) + (xi * xi)); float xPhs = atan2f(xi, xr); float convMag = powf(xMag, p); float convPhs = r * xPhs; float convr = convMag * cosf(convPhs); float convi = convMag * sinf(convPhs); if (std::isnan(convr) || std::isnan(convi)) { convValid = false; } if (isFirstSound) { CONVCHANNEL[i].r = convr; CONVCHANNEL[i].i = convi; } else { float a = CONVCHANNEL[i].r; float b = CONVCHANNEL[i].i; float c = convr; float d = convi; CONVCHANNEL[i].r = a * c - b * d; CONVCHANNEL[i].i = a * d + b * c; } } isFirstSound = false; } // ifft kiss_fftri(fftInverseState, CONVCHANNEL, conv.getWritePointer(convChannel)); // check max float channelMax = conv.findMinMax(convChannel, 0, fftInputLen).getEnd(); max = channelMax > max ? channelMax : max; } delete fftInverseState; delete CONV; // normalize conv.applyGain(1.0f / max); if (!convValid) { AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Error", "Parameters produced NaN value."); return; } setPlayheadAudio(&conv); //[/UserButtonCode_convButton] } else if (buttonThatWasClicked == settingsButton) { //[UserButtonCode_settingsButton] -- add your button handler code here.. AudioDeviceSelectorComponent audioSettingsComp(deviceManager, 0, 256, 0, 256, true, true, true, false); audioSettingsComp.setSize(500, 450); DialogWindow::LaunchOptions o; o.content.setNonOwned(&audioSettingsComp); o.dialogTitle = "Audio Settings"; o.componentToCentreAround = this; o.dialogBackgroundColour = Colours::azure; o.escapeKeyTriggersCloseButton = true; o.useNativeTitleBar = false; o.resizable = false; o.runModal(); ScopedPointer<XmlElement> audioState(deviceManager.createStateXml()); getAppProperties().getUserSettings()->setValue("audioDeviceState", audioState); getAppProperties().getUserSettings()->saveIfNeeded(); //[/UserButtonCode_settingsButton] } else if (buttonThatWasClicked == playButton) { //[UserButtonCode_playButton] -- add your button handler code here.. const ScopedLock pal(playheadAudioLock); playheadState = PlayheadState::playing; playheadAudioSamplesCompleted = 0; //[/UserButtonCode_playButton] } else if (buttonThatWasClicked == loopButton) { //[UserButtonCode_loopButton] -- add your button handler code here.. const ScopedLock pal(playheadAudioLock); playheadState = PlayheadState::looping; //[/UserButtonCode_loopButton] } else if (buttonThatWasClicked == stopButton) { //[UserButtonCode_stopButton] -- add your button handler code here.. const ScopedLock pal(playheadAudioLock); playheadState = PlayheadState::stopped; playheadAudioSamplesCompleted = 0; //[/UserButtonCode_stopButton] } else if (buttonThatWasClicked == qDefaultButton) { //[UserButtonCode_qDefaultButton] -- add your button handler code here.. qSlider->setValue(1.0); //[/UserButtonCode_qDefaultButton] } else if (buttonThatWasClicked == sDefaultButton) { //[UserButtonCode_sDefaultButton] -- add your button handler code here.. sSlider->setValue(1.0); //[/UserButtonCode_sDefaultButton] } else if (buttonThatWasClicked == saveButton) { //[UserButtonCode_saveButton] -- add your button handler code here.. const ScopedLock pal(playheadAudioLock); if (playheadAudio.getNumChannels() > 0 && playheadAudio.getNumSamples() > 0) { FileChooser fileChooser("Save as...", File::nonexistent, "*.wav", true); if (fileChooser.browseForFileToSave(true)) { File outputFile = fileChooser.getResult(); outputFile.deleteFile(); WavAudioFormat wavFormat; ScopedPointer<FileOutputStream> outputFileStream = outputFile.createOutputStream(); ScopedPointer<AudioFormatWriter> writer = wavFormat.createWriterFor(outputFileStream, 44100.0, playheadAudio.getNumChannels(), 16, StringPairArray(), 0); writer->writeFromAudioSampleBuffer(playheadAudio, 0, playheadAudio.getNumSamples()); outputFileStream.release(); } } //[/UserButtonCode_saveButton] } else if (buttonThatWasClicked == inputRemoveButton) { //[UserButtonCode_inputRemoveButton] -- add your button handler code here.. const ScopedLock fl(soundListLock); SparseSet<int> selectedRows = inputFileListComponent->getSelectedRows(); for (int i = 0; i < selectedRows.size(); ++i) { int row = selectedRows[i]; int id = inputFileListComponent->getIdForRow(row); const auto& iter = idToSound.find(id); jassert(iter != idToSound.end()); idToSound.erase(iter); } if (selectedRows.size() > 0) { inputFilesChanged(dontSendNotification); } //[/UserButtonCode_inputRemoveButton] } else if (buttonThatWasClicked == inputAddButton) { //[UserButtonCode_inputAddButton] -- add your button handler code here.. const ScopedLock fl(soundListLock); FileChooser fileChooser("Add sound...", File::nonexistent, "*.wav;*.aif;*.aiff;*.ogg", true); if (fileChooser.browseForMultipleFilesToOpen()) { Array<File> files = fileChooser.getResults(); StringArray filePaths; for (int i = 0; i < files.size(); ++i) { filePaths.add(files[i].getFullPathName()); } filesDropped(filePaths, -1, -1); } //[/UserButtonCode_inputAddButton] } //[UserbuttonClicked_Post] //[/UserbuttonClicked_Post] }
//============================================================================== MainContentComponent::MainContentComponent () : sampleRate(-1.0), gainParam(0.5), nfftParam(0), qParam(1.0), sParam(1.0), conv(0, 0), playheadAudioLock(), playheadState(PlayheadState::stopped), playheadAudio(0, 0), playheadAudioSamplesCompleted(0), soundIdNext(0) { //[Constructor_pre] You can add your own custom stuff here.. formatManager.registerFormat(new WavAudioFormat(), true); formatManager.registerFormat(new AiffAudioFormat(), false); formatManager.registerFormat(new OggVorbisAudioFormat(), false); //[/Constructor_pre] addAndMakeVisible (waveformGroupBox = new GroupComponent (String(), TRANS("Waveform"))); addAndMakeVisible (waveformComponent = new WaveformComponent ("No waveform to display")); addAndMakeVisible (inputGroupBox = new GroupComponent (String(), TRANS("Input"))); addAndMakeVisible (convGroupBox = new GroupComponent (String(), TRANS("Convolution"))); addAndMakeVisible (qSlider = new Slider (String())); qSlider->setRange (0, 8, 0.01); qSlider->setSliderStyle (Slider::LinearHorizontal); qSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 40, 20); qSlider->addListener (this); qSlider->setSkewFactor (0.4); addAndMakeVisible (qLabel = new Label (String(), TRANS("Mag Scale"))); qLabel->setFont (Font (15.00f, Font::plain)); qLabel->setJustificationType (Justification::centredLeft); qLabel->setEditable (false, false, false); qLabel->setColour (TextEditor::textColourId, Colours::black); qLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); addAndMakeVisible (convButton = new TextButton (String())); convButton->setButtonText (TRANS("Convolve")); convButton->addListener (this); addAndMakeVisible (authorLabel = new Label (String(), CharPointer_UTF8 ("\xc2\xa9 Chris Donahue 2016"))); authorLabel->setFont (Font (15.00f, Font::plain)); authorLabel->setJustificationType (Justification::centredLeft); authorLabel->setEditable (false, false, false); authorLabel->setColour (TextEditor::textColourId, Colours::black); authorLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); addAndMakeVisible (settingsButton = new TextButton (String())); settingsButton->setButtonText (TRANS("Audio Settings")); settingsButton->addListener (this); addAndMakeVisible (gainSlider = new Slider (String())); gainSlider->setRange (0, 1, 0.01); gainSlider->setSliderStyle (Slider::LinearHorizontal); gainSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 40, 20); gainSlider->addListener (this); addAndMakeVisible (gainLabel = new Label (String(), TRANS("Gain"))); gainLabel->setFont (Font (15.00f, Font::plain)); gainLabel->setJustificationType (Justification::centredLeft); gainLabel->setEditable (false, false, false); gainLabel->setColour (TextEditor::textColourId, Colours::black); gainLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); addAndMakeVisible (prBehaviorLabel = new Label (String(), TRANS("Mag/Phase Link"))); prBehaviorLabel->setFont (Font (15.00f, Font::plain)); prBehaviorLabel->setJustificationType (Justification::centredLeft); prBehaviorLabel->setEditable (false, false, false); prBehaviorLabel->setColour (TextEditor::textColourId, Colours::black); prBehaviorLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); addAndMakeVisible (prBehaviorComboBox = new ComboBox (String())); prBehaviorComboBox->setEditableText (false); prBehaviorComboBox->setJustificationType (Justification::centredLeft); prBehaviorComboBox->setTextWhenNothingSelected (String()); prBehaviorComboBox->setTextWhenNoChoicesAvailable (TRANS("(no choices)")); prBehaviorComboBox->addItem (TRANS("Independent"), 1); prBehaviorComboBox->addItem (TRANS("Linked"), 2); prBehaviorComboBox->addItem (TRANS("Inverse"), 3); prBehaviorComboBox->addListener (this); addAndMakeVisible (playButton = new TextButton (String())); playButton->setButtonText (TRANS("Play")); playButton->addListener (this); addAndMakeVisible (loopButton = new TextButton (String())); loopButton->setButtonText (TRANS("Loop")); loopButton->addListener (this); addAndMakeVisible (stopButton = new TextButton (String())); stopButton->setButtonText (TRANS("Stop")); stopButton->addListener (this); addAndMakeVisible (qDefaultButton = new TextButton (String())); qDefaultButton->setButtonText (TRANS("Default")); qDefaultButton->addListener (this); addAndMakeVisible (sSlider = new Slider (String())); sSlider->setRange (0, 15, 0.01); sSlider->setSliderStyle (Slider::LinearHorizontal); sSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 40, 20); sSlider->addListener (this); addAndMakeVisible (sDefaultButton = new TextButton (String())); sDefaultButton->setButtonText (TRANS("Default")); sDefaultButton->addListener (this); addAndMakeVisible (nfftSlider = new Slider (String())); nfftSlider->setRange (0, 24, 1); nfftSlider->setSliderStyle (Slider::LinearHorizontal); nfftSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 40, 20); nfftSlider->addListener (this); addAndMakeVisible (nfftLabel = new Label (String(), TRANS("NFFT"))); nfftLabel->setFont (Font (15.00f, Font::plain)); nfftLabel->setJustificationType (Justification::centredLeft); nfftLabel->setEditable (false, false, false); nfftLabel->setColour (TextEditor::textColourId, Colours::black); nfftLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); addAndMakeVisible (saveButton = new TextButton (String())); saveButton->setButtonText (TRANS("Save")); saveButton->addListener (this); addAndMakeVisible (sLabel = new Label (String(), TRANS("Phase Scale"))); sLabel->setFont (Font (15.00f, Font::plain)); sLabel->setJustificationType (Justification::centredLeft); sLabel->setEditable (false, false, false); sLabel->setColour (TextEditor::textColourId, Colours::black); sLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); addAndMakeVisible (inputRemoveButton = new TextButton (String())); inputRemoveButton->setButtonText (TRANS("Remove")); inputRemoveButton->addListener (this); addAndMakeVisible (inputAddButton = new TextButton (String())); inputAddButton->setButtonText (TRANS("Add")); inputAddButton->addListener (this); addAndMakeVisible (inputFileListComponent = new InputFileTableListBox (InputFileTableListBox::PrBehavior::independent)); //[UserPreSize] inputFileListComponent->addChangeListener(this); waveformComponent->setSound(&playheadAudio); setPlayheadAudio(nullptr); //timerCallback(); inputFilesChanged(dontSendNotification); setUiFromParams(dontSendNotification); //[/UserPreSize] setSize (624, 600); //[Constructor] You can add your own custom stuff here.. setAudioChannels(0, JECT_CHANNELS_NUM); startTimerHz(JECT_FPS); //[/Constructor] }