int determineQualityOptionIndex()

in pedalboard/io/WriteableAudioFile.h [47:152]


int determineQualityOptionIndex(juce::AudioFormat *format,
                                const std::string inputString) {
  // Detect the quality level to use based on the string passed in:
  juce::StringArray possibleQualityOptions = format->getQualityOptions();
  int qualityOptionIndex = -1;

  std::string qualityString = juce::String(inputString).trim().toStdString();

  if (!qualityString.empty()) {
    if (inputString == "worst" || inputString == "best" ||
        inputString == "slowest" || inputString == "fastest") {

      const std::string formatName = format->getFormatName().toStdString();

      if (MIN_MAX_QUALITY_OPTIONS.count(formatName) == 1) {
        auto minMaxOptions = MIN_MAX_QUALITY_OPTIONS[formatName];
        if (inputString == "worst" || inputString == "fastest") {
          return possibleQualityOptions.indexOf(minMaxOptions.first);
        } else {
          return possibleQualityOptions.indexOf(minMaxOptions.second);
        }
      } else {
        if (inputString == "worst" || inputString == "fastest" ||
            possibleQualityOptions.isEmpty()) {
          return 0;
        } else {
          return possibleQualityOptions.size() - 1;
        }
      }
    }

    if (!possibleQualityOptions.size()) {
      throw std::domain_error("Unable to parse provided quality value (" +
                              qualityString + "). " +
                              format->getFormatName().toStdString() +
                              "s do not accept quality settings.");
    }

    // Try to match the string against the available options. An exact match
    // is preferred (ignoring case):
    if (qualityOptionIndex == -1 &&
        possibleQualityOptions.contains(qualityString, true)) {
      qualityOptionIndex = possibleQualityOptions.indexOf(qualityString, true);
    }

    // And if no exact match was found, try casting to an integer:
    if (qualityOptionIndex == -1) {
      int numLeadingDigits = 0;
      for (int i = 0; i < qualityString.size(); i++) {
        if (juce::CharacterFunctions::isDigit(qualityString[i])) {
          numLeadingDigits++;
        } else {
          break;
        }
      }

      if (numLeadingDigits) {
        std::string leadingIntValue = qualityString.substr(0, numLeadingDigits);

        // Check to see if any of the valid options start with this option,
        // but make sure we don't select only the prefix of a number
        // (i.e.: if someone gives us "32", don't select "320 kbps")
        for (int i = 0; i < possibleQualityOptions.size(); i++) {
          const juce::String &option = possibleQualityOptions[i];
          if (option.startsWith(leadingIntValue) &&
              option.length() > leadingIntValue.size() &&
              !juce::CharacterFunctions::isDigit(
                  option[leadingIntValue.size()])) {
            qualityOptionIndex = i;
            break;
          }
        }
      } else {
        // If our search string doesn't start with leading digits,
        // check for a substring:
        for (int i = 0; i < possibleQualityOptions.size(); i++) {
          if (possibleQualityOptions[i].containsIgnoreCase(qualityString)) {
            qualityOptionIndex = i;
            break;
          }
        }
      }
    }

    // If we get here, we received a string we were unable to parse,
    // so the user should probably know about it:
    if (qualityOptionIndex == -1) {
      throw std::domain_error(
          "Unable to parse provided quality value (" + qualityString +
          "). Valid values for " + format->getFormatName().toStdString() +
          "s are: " +
          possibleQualityOptions.joinIntoString(", ").toStdString());
    }
  }

  if (qualityOptionIndex == -1) {
    if (possibleQualityOptions.size()) {
      // Choose the best quality by default if possible:
      qualityOptionIndex = possibleQualityOptions.size() - 1;
    } else {
      qualityOptionIndex = 0;
    }
  }

  return qualityOptionIndex;
}