Example usage for javax.sound.sampled AudioFileFormat AudioFileFormat

List of usage examples for javax.sound.sampled AudioFileFormat AudioFileFormat

Introduction

In this page you can find the example usage for javax.sound.sampled AudioFileFormat AudioFileFormat.

Prototype

public AudioFileFormat(Type type, AudioFormat format, int frameLength) 

Source Link

Document

Constructs an audio file format object.

Usage

From source file:marytts.tools.perceptiontest.UtterancePlayRequestHandler.java

private void process(Address serverAddressAtClient, Map<String, String> queryItems, HttpResponse response) {

    boolean streamingAudio = true;
    AudioFileFormat.Type audioFileFormatType = AudioFileFormat.Type.WAVE;
    AudioFormat audioFormat = Voice.AF16000;
    AudioFileFormat audioFileFormat = new AudioFileFormat(audioFileFormatType, audioFormat,
            AudioSystem.NOT_SPECIFIED);

    final UtteranceRequest maryRequest = new UtteranceRequest(getId(), audioFileFormat, streamingAudio);
    // Process the request and send back the data
    boolean ok = true;
    //boolean okTest1 = queryItems.containsKey("EMAIL");
    //boolean okTest2 = queryItems.containsKey("PRESENT_SAMPLE_NUMBER");
    //boolean okTest3 = queryItems.containsKey("PERCEPTION_RESULT");

    boolean okTest = queryItems.containsKey("PRESENT_SAMPLE_NUMBER");

    //if(okTest1 && okTest2) {
    if (!okTest) {
        String message = "Problem reading input";
        logger.warn(message);//ww w.j a v  a  2 s.  c  om
        MaryHttpServerUtils.errorInternalServerError(response, message, new Exception());
        ok = false;
    }

    if (ok) {
        int presentSample = (new Integer(queryItems.get("PRESENT_SAMPLE_NUMBER"))).intValue();
        final String waveFile = this.infoRH.getSampleWaveFile(presentSample);

        if (streamingAudio) {
            // Start two separate threads:
            // 1. one thread to process the request;
            new Thread("RH " + maryRequest.getId()) {
                public void run() {
                    Logger myLogger = MaryUtils.getLogger(this.getName());
                    try {
                        maryRequest.process(waveFile);
                        myLogger.info("Streaming request processed successfully.");
                    } catch (Throwable t) {
                        myLogger.error("Processing failed.", t);
                    }
                }
            }.start();

            // 2. one thread to take the audio data as it becomes available
            //    and write it into the ProducingNHttpEntity.
            // The second one does not depend on the first one practically,
            // because the AppendableSequenceAudioInputStream returned by
            // maryRequest.getAudio() was already created in the constructor of Request.
            AudioInputStream audio = maryRequest.getAudio();
            assert audio != null : "Streaming audio but no audio stream -- very strange indeed! :-(";
            AudioFileFormat.Type audioType = maryRequest.getAudioFileFormat().getType();
            AudioStreamNHttpEntity entity = new AudioStreamNHttpEntity(maryRequest);
            new Thread(entity, "HTTPWriter " + maryRequest.getId()).start();
            // entity knows its contentType, no need to set explicitly here.
            response.setEntity(entity);
            response.setStatusCode(HttpStatus.SC_OK);
            return;
        } else { // not streaming audio
            // Process input data to output data
            try {
                maryRequest.process(waveFile); // this may take some time
            } catch (Throwable e) {
                String message = "Processing failed.";
                logger.error(message, e);
                MaryHttpServerUtils.errorInternalServerError(response, message, e);
                ok = false;
            }
            if (ok) {
                // Write output data to client
                try {
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    maryRequest.writeOutputData(outputStream);
                    String contentType;
                    contentType = MaryHttpServerUtils.getMimeType(maryRequest.getAudioFileFormat().getType());
                    MaryHttpServerUtils.toHttpResponse(outputStream.toByteArray(), response, contentType);
                } catch (Exception e) {
                    String message = "Cannot write output";
                    logger.warn(message, e);
                    MaryHttpServerUtils.errorInternalServerError(response, message, e);
                    ok = false;
                }
            }
        }
    }

    if (ok)
        logger.info("Request handled successfully.");
    else
        logger.info("Request couldn't be handled successfully.");
    if (MaryRuntimeUtils.lowMemoryCondition()) {
        logger.info("Low memory condition detected (only " + MaryUtils.availableMemory()
                + " bytes left). Triggering garbage collection.");
        Runtime.getRuntime().gc();
        logger.info("After garbage collection: " + MaryUtils.availableMemory() + " bytes available.");
    }

}

From source file:marytts.server.http.SynthesisRequestHandler.java

public void process(Address serverAddressAtClient, Map<String, String> queryItems, HttpResponse response) {
    if (queryItems == null || !(queryItems.containsKey("INPUT_TYPE") && queryItems.containsKey("OUTPUT_TYPE")
            && queryItems.containsKey("LOCALE") && queryItems.containsKey("INPUT_TEXT"))) {
        MaryHttpServerUtils.errorMissingQueryParameter(response,
                "'INPUT_TEXT' and 'INPUT_TYPE' and 'OUTPUT_TYPE' and 'LOCALE'");
        return;//from ww w  . ja va 2s  .  c o  m
    }

    String inputText = queryItems.get("INPUT_TEXT");

    MaryDataType inputType = MaryDataType.get(queryItems.get("INPUT_TYPE"));
    if (inputType == null) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "INPUT_TYPE", queryItems.get("INPUT_TYPE"),
                null);
        return;
    }

    MaryDataType outputType = MaryDataType.get(queryItems.get("OUTPUT_TYPE"));
    if (outputType == null) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "OUTPUT_TYPE",
                queryItems.get("OUTPUT_TYPE"), null);
        return;
    }
    boolean isOutputText = true;
    boolean streamingAudio = false;
    AudioFileFormat.Type audioFileFormatType = null;
    if (outputType.name().contains("AUDIO")) {
        isOutputText = false;
        String audioTypeName = queryItems.get("AUDIO");
        if (audioTypeName == null) {
            MaryHttpServerUtils.errorMissingQueryParameter(response, "'AUDIO' when OUTPUT_TYPE=AUDIO");
            return;
        }
        if (audioTypeName.endsWith("_STREAM")) {
            streamingAudio = true;
        }
        int lastUnderscore = audioTypeName.lastIndexOf('_');
        if (lastUnderscore != -1) {
            audioTypeName = audioTypeName.substring(0, lastUnderscore);
        }
        try {
            audioFileFormatType = MaryAudioUtils.getAudioFileFormatType(audioTypeName);
        } catch (Exception ex) {
        }
        if (audioFileFormatType == null) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "AUDIO", queryItems.get("AUDIO"), null);
            return;
        } else if (audioFileFormatType.toString().equals("MP3") && !MaryRuntimeUtils.canCreateMP3()) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "AUDIO", queryItems.get("AUDIO"),
                    "Conversion to MP3 not supported.");
            return;
        } else if (audioFileFormatType.toString().equals("Vorbis") && !MaryRuntimeUtils.canCreateOgg()) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "AUDIO", queryItems.get("AUDIO"),
                    "Conversion to OGG Vorbis format not supported.");
            return;
        }
    }
    // optionally, there may be output type parameters
    // (e.g., the list of features to produce for the output type TARGETFEATURES)
    String outputTypeParams = queryItems.get("OUTPUT_TYPE_PARAMS");

    Locale locale = MaryUtils.string2locale(queryItems.get("LOCALE"));
    if (locale == null) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "LOCALE", queryItems.get("LOCALE"), null);
        return;
    }

    Voice voice = null;
    String voiceName = queryItems.get("VOICE");
    if (voiceName != null) {
        if (voiceName.equals("male") || voiceName.equals("female")) {
            voice = Voice.getVoice(locale, new Voice.Gender(voiceName));
        } else {
            voice = Voice.getVoice(voiceName);
        }
        if (voice == null) {
            // a voice name was given but there is no such voice
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "VOICE", queryItems.get("VOICE"), null);
            return;
        }
    }
    if (voice == null) { // no voice tag -- use locale default if it exists.
        voice = Voice.getDefaultVoice(locale);
        logger.debug("No voice requested -- using default " + voice);
    }

    String style = queryItems.get("STYLE");
    if (style == null)
        style = "";

    String effects = toRequestedAudioEffectsString(queryItems);
    if (effects.length() > 0)
        logger.debug("Audio effects requested: " + effects);
    else
        logger.debug("No audio effects requested");

    String logMsg = queryItems.get("LOG");
    if (logMsg != null) {
        logger.info("Connection info: " + logMsg);
    }

    // Now, the parse is complete.

    // Construct audio file format -- even when output is not AUDIO,
    // in case we need to pass via audio to get our output type.
    if (audioFileFormatType == null) {
        audioFileFormatType = AudioFileFormat.Type.AU;
    }
    AudioFormat audioFormat;
    if (audioFileFormatType.toString().equals("MP3")) {
        audioFormat = MaryRuntimeUtils.getMP3AudioFormat();
    } else if (audioFileFormatType.toString().equals("Vorbis")) {
        audioFormat = MaryRuntimeUtils.getOggAudioFormat();
    } else if (voice != null) {
        audioFormat = voice.dbAudioFormat();
    } else {
        audioFormat = Voice.AF16000;
    }
    AudioFileFormat audioFileFormat = new AudioFileFormat(audioFileFormatType, audioFormat,
            AudioSystem.NOT_SPECIFIED);

    final Request maryRequest = new Request(inputType, outputType, locale, voice, effects, style, getId(),
            audioFileFormat, streamingAudio, outputTypeParams);

    // Process the request and send back the data
    boolean ok = true;
    try {
        maryRequest.setInputData(inputText);
        logger.info("Read: " + inputText);
    } catch (Exception e) {
        String message = "Problem reading input";
        logger.warn(message, e);
        MaryHttpServerUtils.errorInternalServerError(response, message, e);
        ok = false;
    }
    if (ok) {
        if (streamingAudio) {
            // Start two separate threads:
            // 1. one thread to process the request;
            new Thread("RH " + maryRequest.getId()) {
                public void run() {
                    Logger myLogger = MaryUtils.getLogger(this.getName());
                    try {
                        maryRequest.process();
                        myLogger.info("Streaming request processed successfully.");
                    } catch (Throwable t) {
                        myLogger.error("Processing failed.", t);
                    }
                }
            }.start();

            // 2. one thread to take the audio data as it becomes available
            //    and write it into the ProducingNHttpEntity.
            // The second one does not depend on the first one practically,
            // because the AppendableSequenceAudioInputStream returned by
            // maryRequest.getAudio() was already created in the constructor of Request.
            AudioInputStream audio = maryRequest.getAudio();
            assert audio != null : "Streaming audio but no audio stream -- very strange indeed! :-(";
            AudioFileFormat.Type audioType = maryRequest.getAudioFileFormat().getType();
            AudioStreamNHttpEntity entity = new AudioStreamNHttpEntity(maryRequest);
            new Thread(entity, "HTTPWriter " + maryRequest.getId()).start();
            // entity knows its contentType, no need to set explicitly here.
            response.setEntity(entity);
            response.setStatusCode(HttpStatus.SC_OK);
            return;
        } else { // not streaming audio
            // Process input data to output data
            try {
                maryRequest.process(); // this may take some time
            } catch (Throwable e) {
                String message = "Processing failed.";
                logger.error(message, e);
                MaryHttpServerUtils.errorInternalServerError(response, message, e);
                ok = false;
            }
            if (ok) {
                // Write output data to client
                try {
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    maryRequest.writeOutputData(outputStream);
                    String contentType;
                    if (maryRequest.getOutputType().isXMLType() || maryRequest.getOutputType().isTextType()) //text output
                        contentType = "text/plain; charset=UTF-8";
                    else //audio output
                        contentType = MaryHttpServerUtils
                                .getMimeType(maryRequest.getAudioFileFormat().getType());
                    MaryHttpServerUtils.toHttpResponse(outputStream.toByteArray(), response, contentType);
                } catch (Exception e) {
                    String message = "Cannot write output";
                    logger.warn(message, e);
                    MaryHttpServerUtils.errorInternalServerError(response, message, e);
                    ok = false;
                }
            }
        }
    }

    if (ok)
        logger.info("Request handled successfully.");
    else
        logger.info("Request couldn't be handled successfully.");
    if (MaryRuntimeUtils.lowMemoryCondition()) {
        logger.info("Low memory condition detected (only " + MaryUtils.availableMemory()
                + " bytes left). Triggering garbage collection.");
        Runtime.getRuntime().gc();
        logger.info("After garbage collection: " + MaryUtils.availableMemory() + " bytes available.");
    }
}

From source file:marytts.server.http.MivoqSynthesisRequestHandler.java

public void process(Address serverAddressAtClient, Map<String, String> queryItems, HttpResponse response) {
    if (queryItems == null || !(queryItems.containsKey("input[type]") && queryItems.containsKey("output[type]")
            && queryItems.containsKey("input[content]"))) {
        MaryHttpServerUtils.errorMissingQueryParameter(response,
                "'input[content]' and 'input[type]' and 'output[type]'");
        return;/* w  ww.jav  a2s  .c om*/
    }

    String inputContent = queryItems.get("input[content]");
    String inputTypeString = queryItems.get("input[type]");
    String outputTypeString = queryItems.get("output[type]");
    MaryDataType inputType = MaryDataType.get(inputTypeString);
    if (inputType == null) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "input[type]", inputTypeString, null);
        return;
    }

    MaryDataType outputType = MaryDataType.get(outputTypeString);
    if (outputType == null) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "output[type]", outputTypeString, null);
        return;
    }

    if (inputType.isTextType()) {
        if (!queryItems.containsKey("input[locale]")) {
            MaryHttpServerUtils.errorMissingQueryParameter(response,
                    "'input[locale]', needed for input[type] = " + inputTypeString);
        }
    }
    String inputLocaleString = queryItems.get("input[locale]");
    Locale inputLocale = MaryUtils.string2locale(inputLocaleString);
    if (inputLocale == null) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "input[locale]", inputLocaleString, null);
        return;
    }

    boolean isOutputText = true;
    boolean streamingAudio = false;
    AudioFileFormat.Type audioFileFormatType = null;
    if (outputType.name().contains("AUDIO")) {
        isOutputText = false;
        String outputFormatString = queryItems.get("output[format]");
        if (outputFormatString == null) {
            MaryHttpServerUtils.errorMissingQueryParameter(response,
                    "'output[format]' when output[type] = AUDIO");
            return;
        }
        if (outputFormatString.endsWith("_STREAM")) {
            streamingAudio = true;
        }
        int lastUnderscore = outputFormatString.lastIndexOf('_');
        if (lastUnderscore != -1) {
            outputFormatString = outputFormatString.substring(0, lastUnderscore);
        }
        try {
            audioFileFormatType = MaryAudioUtils.getAudioFileFormatType(outputFormatString);
        } catch (Exception ex) {
        }
        if (audioFileFormatType == null) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "output[format]", outputFormatString,
                    null);
            return;
        } else if (audioFileFormatType.toString().equals("MP3") && !MaryRuntimeUtils.canCreateMP3()) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "output[format]", outputFormatString,
                    "Conversion to MP3 not supported.");
            return;
        } else if (audioFileFormatType.toString().equals("Vorbis") && !MaryRuntimeUtils.canCreateOgg()) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "output[format]", outputFormatString,
                    "Conversion to OGG Vorbis format not supported.");
            return;
        }
    }

    Voice voice = null;
    String voiceGenderString = queryItems.get("voice[gender]");
    Voice.Gender voiceGender = null;
    if (voiceGenderString != null) {
        if (!(voiceGenderString.equals("male") || voiceGenderString.equals("female")
                || voiceGenderString.equals("neutral"))) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "voice[gender]", voiceGenderString,
                    null);
        }
        voiceGender = new Voice.Gender(voiceGenderString);
    }
    String voiceAgeString = queryItems.get("voice[age]");
    int voiceAge = -1;
    if (voiceAgeString != null) {
        voiceAge = Integer.parseInt(voiceAgeString);
        if (voiceAge < 0) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "voice[age]", voiceAgeString, null);
        }
    }
    String voiceVariantString = queryItems.get("voice[variant]");
    int voiceVariant = -1;
    if (voiceVariantString != null) {
        voiceVariant = Integer.parseInt(voiceVariantString);
        if (voiceVariant < 0) {
            MaryHttpServerUtils.errorWrongQueryParameterValue(response, "voice[variant]", voiceVariantString,
                    null);
        }
    }
    String utteranceStyle = queryItems.get("utterance[style]");
    if (utteranceStyle == null) {
        utteranceStyle = "";
    }

    String voiceName = queryItems.get("voice[name]");
    String[] voiceNameList = null;
    if (voiceName != null) {
        voiceNameList = voiceName.split(" ");
    }

    String utteranceEffects = queryItems.get("utterance[effects]");
    if (utteranceEffects == null) {
        utteranceEffects = "";
    }
    if (utteranceEffects.length() > 0)
        logger.debug("Audio effects requested: " + utteranceEffects);
    else
        logger.debug("No audio effects requested");

    // TODO(START,Parsing)

    // optionally, there may be output type parameters
    // (e.g., the list of features to produce for the output type TARGETFEATURES)
    String outputTypeParams = queryItems.get("OUTPUT_TYPE_PARAMS");

    String logMsg = queryItems.get("LOG");
    if (logMsg != null) {
        logger.info("Connection info: " + logMsg);
    }

    // TODO(END,Parsing)

    List<Voice> voiceResult = Voice.getVoiceWithSSMLAlgorythm(inputLocale, voiceGender, voiceNameList,
            voiceAge);
    if (voice == null) { // no voice tag -- use locale default if it exists.
        voice = Voice.getDefaultVoice(inputLocale);
        logger.debug("No voice requested -- using default " + voice);
    }
    if (voiceResult.isEmpty()) {
        MaryHttpServerUtils.errorWrongQueryParameterValue(response, "input[] and voice[]",
                "No suitable voice found for the requested configuration", null);
        return;
    }
    if (voiceVariant > 0) {
        voiceVariant--;
        if (voiceVariant >= voiceResult.size()) {
            voiceVariant = voiceResult.size() - 1;
        }
    } else {
        voiceVariant = 0;
    }
    voice = voiceResult.get(voiceVariant);
    inputLocale = voice.getLocale();

    String utteranceStyleEffects = "";
    if (fakeStylesByGender.containsKey(voice.gender().toString())) {
        HashMap<String, String> s = fakeStylesByGender.get(voice.gender().toString());
        if (s.containsKey(utteranceStyle)) {
            utteranceStyleEffects = s.get(utteranceStyle);
        }
    }
    HashMap<String, Object> effects_values = new HashMap<String, Object>();
    if (utteranceStyleEffects.length() > 0) {
        JSONArray effects = new JSONArray(utteranceStyleEffects);
        for (int i = 0; i < effects.length(); i++) {
            JSONObject obj = effects.getJSONObject(i);
            parseEffectsIntoHashMap(effectsRegistry, effects_values, obj);
            // System.out.println(toOldStyleEffectsString(registry, effects_values));
        }
        // System.out.println(toOldStyleEffectsString(registry, effects_values));
    }
    if (utteranceEffects.length() > 0) {
        JSONArray effects = new JSONArray(utteranceEffects);
        for (int i = 0; i < effects.length(); i++) {
            JSONObject obj = effects.getJSONObject(i);
            parseEffectsIntoHashMap(effectsRegistry, effects_values, obj);
            // System.out.println(toOldStyleEffectsString(registry, effects_values));
        }
        // System.out.println(toOldStyleEffectsString(registry, effects_values));
    }
    utteranceEffects = toOldStyleEffectsString(effectsRegistry, effects_values);
    if (utteranceEffects.length() > 0)
        logger.debug("Audio effects requested: " + utteranceEffects);
    else
        logger.debug("No audio effects requested");
    // Now, the parse is complete.

    // Construct audio file format -- even when output is not AUDIO,
    // in case we need to pass via audio to get our output type.
    if (audioFileFormatType == null) {
        audioFileFormatType = AudioFileFormat.Type.AU;
    }
    AudioFormat audioFormat;
    if (audioFileFormatType.toString().equals("MP3")) {
        audioFormat = MaryRuntimeUtils.getMP3AudioFormat();
    } else if (audioFileFormatType.toString().equals("Vorbis")) {
        audioFormat = MaryRuntimeUtils.getOggAudioFormat();
    } else if (voice != null) {
        audioFormat = voice.dbAudioFormat();
    } else {
        audioFormat = Voice.AF16000;
    }
    AudioFileFormat audioFileFormat = new AudioFileFormat(audioFileFormatType, audioFormat,
            AudioSystem.NOT_SPECIFIED);

    final Request maryRequest = new Request(inputType, outputType, inputLocale, voice, utteranceEffects,
            utteranceStyle, getId(), audioFileFormat, streamingAudio, outputTypeParams);

    // Process the request and send back the data
    boolean ok = true;
    try {
        maryRequest.setInputData(inputContent);
        logger.info("Read: " + inputContent);
    } catch (Exception e) {
        String message = "Problem reading input";
        logger.warn(message, e);
        MaryHttpServerUtils.errorInternalServerError(response, message, e);
        ok = false;
    }
    if (ok) {
        if (streamingAudio) {
            // Start two separate threads:
            // 1. one thread to process the request;
            new Thread("RH " + maryRequest.getId()) {
                public void run() {
                    Logger myLogger = MaryUtils.getLogger(this.getName());
                    try {
                        maryRequest.process();
                        myLogger.info("Streaming request processed successfully.");
                    } catch (Throwable t) {
                        myLogger.error("Processing failed.", t);
                    }
                }
            }.start();

            // 2. one thread to take the audio data as it becomes available
            //    and write it into the ProducingNHttpEntity.
            // The second one does not depend on the first one practically,
            // because the AppendableSequenceAudioInputStream returned by
            // maryRequest.getAudio() was already created in the constructor of Request.
            AudioInputStream audio = maryRequest.getAudio();
            assert audio != null : "Streaming audio but no audio stream -- very strange indeed! :-(";
            AudioFileFormat.Type audioType = maryRequest.getAudioFileFormat().getType();
            AudioStreamNHttpEntity entity = new AudioStreamNHttpEntity(maryRequest);
            new Thread(entity, "HTTPWriter " + maryRequest.getId()).start();
            // entity knows its contentType, no need to set explicitly here.
            response.setEntity(entity);
            response.setStatusCode(HttpStatus.SC_OK);
            return;
        } else { // not streaming audio
            // Process input data to output data
            try {
                maryRequest.process(); // this may take some time
            } catch (Throwable e) {
                String message = "Processing failed.";
                logger.error(message, e);
                MaryHttpServerUtils.errorInternalServerError(response, message, e);
                ok = false;
            }
            if (ok) {
                // Write output data to client
                try {
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    maryRequest.writeOutputData(outputStream);
                    String contentType;
                    if (maryRequest.getOutputType().isXMLType() || maryRequest.getOutputType().isTextType()) //text output
                        contentType = "text/plain; charset=UTF-8";
                    else //audio output
                        contentType = MaryHttpServerUtils
                                .getMimeType(maryRequest.getAudioFileFormat().getType());
                    MaryHttpServerUtils.toHttpResponse(outputStream.toByteArray(), response, contentType);
                } catch (Exception e) {
                    String message = "Cannot write output";
                    logger.warn(message, e);
                    MaryHttpServerUtils.errorInternalServerError(response, message, e);
                    ok = false;
                }
            }
        }
    }

    if (ok)
        logger.info("Request handled successfully.");
    else
        logger.info("Request couldn't be handled successfully.");
    if (MaryRuntimeUtils.lowMemoryCondition()) {
        logger.info("Low memory condition detected (only " + MaryUtils.availableMemory()
                + " bytes left). Triggering garbage collection.");
        Runtime.getRuntime().gc();
        logger.info("After garbage collection: " + MaryUtils.availableMemory() + " bytes available.");
    }
}