File indexing completed on 2024-05-12 03:52:13
0001 /**************************************************************************** 0002 ** 0003 ** Copyright (C) 2016 by Sandro S. Andrade <sandroandrade@kde.org> 0004 ** 0005 ** This program is free software; you can redistribute it and/or 0006 ** modify it under the terms of the GNU General Public License as 0007 ** published by the Free Software Foundation; either version 2 of 0008 ** the License or (at your option) version 3 or any later version 0009 ** accepted by the membership of KDE e.V. (or its successor approved 0010 ** by the membership of KDE e.V.), which shall act as a proxy 0011 ** defined in Section 14 of version 3 of the license. 0012 ** 0013 ** This program is distributed in the hope that it will be useful, 0014 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0016 ** GNU General Public License for more details. 0017 ** 0018 ** You should have received a copy of the GNU General Public License 0019 ** along with this program. If not, see <http://www.gnu.org/licenses/>. 0020 ** 0021 ****************************************************************************/ 0022 0023 #include "csoundsoundcontroller.h" 0024 #include "csengine.h" 0025 0026 #include <QLoggingCategory> 0027 #include <QtMath> 0028 #include <QtQml> 0029 0030 Q_DECLARE_LOGGING_CATEGORY(MINUETANDROID) 0031 0032 CsoundSoundController::CsoundSoundController(QObject *parent) 0033 : Minuet::ISoundController(parent), m_csoundEngine(new CsEngine) 0034 { 0035 qmlRegisterType<CsoundSoundController>("org.kde.minuet", 1, 0, "CsoundSoundController"); 0036 openExerciseFile(); 0037 // setQuestionLabel("new question"); 0038 } 0039 0040 void CsoundSoundController::openExerciseFile() 0041 { 0042 QStringList templateList; 0043 templateList.append(QStringLiteral("assets:/share/template.csd")); 0044 // templateList.append(QStringLiteral("assets:/share/template_rhythm.csd")); 0045 0046 qDebug() << "DIRPATH: " << QCoreApplication::applicationDirPath(); 0047 qDebug() << "ASSETSPATH: " << QDir("assets:/").canonicalPath(); 0048 qDebug() << "QStandardPaths::ApplicationsLocation: " 0049 << QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); 0050 qDebug() << "QStandardPaths::GenericDataLocation: " 0051 << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); 0052 qDebug() << "QStandardPaths::AppDataLocation: " 0053 << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); 0054 qDebug() << "QStandardPaths::AppLocalDataLocation: " 0055 << QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation); 0056 qDebug() << "QStandardPaths::AppConfigLocation: " 0057 << QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation); 0058 QDir appDir(QCoreApplication::applicationDirPath()); 0059 qDebug() << "Contains libfluidOpcodes.so? " 0060 << appDir.entryList(QDir::Files).contains("libfluidOpcodes.so"); 0061 qDebug() << "DIRPATH: " << appDir << " Contents: " << appDir.entryList(QDir::AllEntries); 0062 appDir.cdUp(); 0063 qDebug() << "DIRPATH: " << appDir << " Contents: " << appDir.entryList(QDir::AllEntries); 0064 appDir.cdUp(); 0065 qDebug() << "DIRPATH: " << appDir << " Contents: " << appDir.entryList(QDir::AllEntries); 0066 QDir reserved("/data/data/org.kde.minuet/qt-reserved-files/"); 0067 qDebug() << "RESERVED: " << reserved << " Contents: " << reserved.entryList(QDir::AllEntries); 0068 0069 QDirIterator it("/", QDirIterator::Subdirectories); 0070 while (it.hasNext()) { 0071 qDebug() << "FILE: " << it.next(); 0072 } 0073 foreach (const QString &templateString, templateList) { 0074 QFile sfile(templateString); 0075 if (!sfile.open(QIODevice::ReadOnly | QIODevice::Text)) { 0076 return; 0077 } 0078 0079 QTextStream in(&sfile); 0080 QString lineData; 0081 QString tempBeginLine; 0082 QString tempEndLine; 0083 0084 while (!in.atEnd()) { 0085 lineData = in.readLine(); 0086 lineData.replace("APPDIRPATH", QCoreApplication::applicationDirPath()); 0087 tempBeginLine = tempBeginLine + lineData + '\n'; 0088 if (lineData.contains("<CsScore>")) { 0089 m_begLine.append(tempBeginLine); 0090 break; 0091 } 0092 } 0093 0094 while (!in.atEnd()) { 0095 lineData = in.readLine(); 0096 tempEndLine += lineData + '\n'; 0097 } 0098 m_endLine.append(tempEndLine); 0099 } 0100 qDebug() << "m_begLine: " << m_begLine; 0101 qDebug() << "m_endLine: " << m_endLine; 0102 } 0103 0104 void CsoundSoundController::appendEvent(QList<unsigned int> midiNotes, QList<float> barStartInfo, 0105 QString playMode) 0106 { 0107 // TODO : use grantlee processing or any other text template library 0108 int templateNumber = playMode == "rhythm" ? 1 : 0; 0109 QString content; 0110 QString fifthParam = QStringLiteral("100"); 0111 QFile m_csdFileOpen(QStringLiteral("./template.csd")); 0112 0113 qDebug() << "CREATING " << QDir::currentPath() + "/template.csd"; 0114 if (!m_csdFileOpen.isOpen()) { 0115 m_csdFileOpen.open(QIODevice::ReadWrite | QIODevice::Text); 0116 } 0117 m_csdFileOpen.resize(0); 0118 0119 if (playMode == "rhythm") { 0120 QString wave = QStringLiteral("f 1 0 16384 10 1\n\n"); 0121 content += wave; 0122 fifthParam = QStringLiteral(""); 0123 } 0124 0125 for (int i = 0; i < midiNotes.count(); i++) { 0126 QString initScore = QString("i 1 %1 %2 %3 %4\n") 0127 .arg(QString::number(barStartInfo.at(i))) 0128 .arg(QString::number(1)) 0129 .arg(QString::number(midiNotes.at(i))) 0130 .arg(fifthParam); 0131 // content += initScore; 0132 } 0133 0134 if (playMode != "rhythm") { 0135 QString instrInit 0136 = "i 99 0 " + QString::number(barStartInfo.at(barStartInfo.count() - 1) + 1) 0137 + "\ne\n"; // instrument will be active till the end of the notes +1 second 0138 // content += instrInit; 0139 } 0140 0141 QString templateContent = m_begLine[templateNumber] + content + m_endLine[templateNumber]; 0142 m_csdFileOpen.seek(0); 0143 QByteArray contentByte = templateContent.toUtf8(); 0144 m_csdFileOpen.write(contentByte); 0145 } 0146 0147 CsoundSoundController::~CsoundSoundController() 0148 { 0149 delete m_csoundEngine; 0150 } 0151 0152 void CsoundSoundController::prepareFromExerciseOptions(QJsonArray selectedExerciseOptions) 0153 { 0154 float barStart = 0; 0155 QList<unsigned int> midiNotes; 0156 QList<float> barStartInfo; 0157 0158 if (m_playMode == "rhythm") { 0159 for (int k = 0; k < 4; ++k) { 0160 midiNotes.append(80); 0161 barStartInfo.append(barStart++); 0162 } 0163 } 0164 0165 int exerciseOptionsSize = selectedExerciseOptions.size(); 0166 for (int i = 0; i < exerciseOptionsSize; ++i) { 0167 QString sequence 0168 = selectedExerciseOptions[i].toObject()[QStringLiteral("sequence")].toString(); 0169 0170 unsigned int chosenRootNote 0171 = selectedExerciseOptions[i].toObject()[QStringLiteral("rootNote")].toString().toInt(); 0172 if (m_playMode != "rhythm") { 0173 midiNotes.append(chosenRootNote); 0174 barStartInfo.append(barStart); 0175 0176 unsigned int j = 1; 0177 foreach (const QString &additionalNote, sequence.split(' ')) { 0178 midiNotes.append(chosenRootNote + additionalNote.toInt()); 0179 barStartInfo.append((m_playMode == "scale") ? barStart + j : barStart); 0180 ++j; 0181 } 0182 barStart++; 0183 } else { 0184 midiNotes.append(80); 0185 barStartInfo.append(barStart); 0186 foreach (QString additionalNote, sequence.split(' ')) { // krazy:exclude=foreach 0187 midiNotes.append(37); 0188 barStartInfo.append(barStart); 0189 float dotted = 1; 0190 if (additionalNote.endsWith('.')) { 0191 dotted = 1.5; 0192 additionalNote.chop(1); 0193 } 0194 barStart += dotted * 1 * (4.0 / additionalNote.toInt()); 0195 } 0196 } 0197 } 0198 0199 if (m_playMode == "rhythm") { 0200 midiNotes.append(80); 0201 barStartInfo.append(barStart); 0202 } 0203 appendEvent(midiNotes, barStartInfo, m_playMode); 0204 } 0205 0206 void CsoundSoundController::prepareFromMidiFile(const QString &fileName) 0207 { 0208 Q_UNUSED(fileName) 0209 } 0210 0211 void CsoundSoundController::play() 0212 { 0213 m_csoundEngine->start(); 0214 setState(PlayingState); 0215 } 0216 0217 void CsoundSoundController::pause() {} 0218 0219 void CsoundSoundController::stop() 0220 { 0221 m_csoundEngine->stop(); 0222 setState(StoppedState); 0223 } 0224 0225 void CsoundSoundController::reset() {} 0226 0227 void CsoundSoundController::setPitch(qint8 pitch) 0228 { 0229 Q_UNUSED(pitch) 0230 } 0231 0232 void CsoundSoundController::setVolume(quint8 volume) 0233 { 0234 Q_UNUSED(volume) 0235 } 0236 0237 void CsoundSoundController::setTempo(quint8 tempo) 0238 { 0239 Q_UNUSED(tempo) 0240 } 0241 0242 //#include "moc_csoundsoundcontroller.cpp"