示例#1
0
void HtmlRenderer::renderImage(const ImageTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    UNUSED_ARG(ancestorNodes);

    if (node == 0) {
        return;
    }

    assert(node->hasChildren() == false);

    if (node->refType() == ImageTreeNode::NO_REF) {
        // Inline image like "![img](url)"
        renderImageTag(node->url(), node->title(), node->altText(), outputDevice(), isSelfClosingVoidTagsEnabled());
    } else {
        // Reference image like "![img][ref]" or "![img-ref]" or "![img-ref][]"
        const VfmdLinkRefMap *linkRefMap = node->linkRefMap();
        VfmdByteArray refId = node->refIdText().simplified().toLowerCase();
        if ((refId.size() > 0) && (linkRefMap->hasData(refId))) {
            // We found a definition for this ref id
            VfmdByteArray url = linkRefMap->linkUrl(refId);
            VfmdByteArray title = linkRefMap->linkTitle(refId);
            renderImageTag(url, title, node->altText(), outputDevice(), isSelfClosingVoidTagsEnabled());
        } else {
            // We didn't find a definition for this ref id
            outputDevice()->write("![", 2);
            outputDevice()->write(node->altText());
            HtmlTextRenderer::renderText(outputDevice(), node->closeTagText(),
                                         isSelfClosingVoidTagsEnabled(),
                                         isLineBreakOnNewlinesEnabled());
        }
    }
}
示例#2
0
void TreeRenderer::renderTreeText(const VfmdElementTreeNode *node, const VfmdElementTreeNodeStack *ancestorNodes,
                                  const VfmdByteArray &text,
                                  bool decorate)
{
    const char *data_ptr = text.data();
    size_t sz = text.size();
    if (data_ptr && sz) {
        if (decorate) {
            renderTreePrefix(ancestorNodes, (node->hasNext()? "|  \'" : "   \'"));
        } else {
            renderTreePrefix(ancestorNodes, (node->hasNext()? "|  " : "   "));
        }
        for (unsigned int i = 0; i < sz; i++) {
            if (data_ptr[i] == '\n') {
                if (decorate) {
                    outputDevice()->write("\\n\'\n");
                    if (i < (sz - 1)) {
                        renderTreePrefix(ancestorNodes, (node->hasNext()? "|  \'" : "   \'"));
                    }
                } else {
                    outputDevice()->write('\n');
                    if (i < (sz - 1)) {
                        renderTreePrefix(ancestorNodes, (node->hasNext()? "|  " : "   "));
                    }
                }
            } else {
                outputDevice()->write(data_ptr[i]);
            }
        }
        if (text.lastByte() != '\n') {
            outputDevice()->write(decorate? "\'\n" : "\n");
        }
    }
}
示例#3
0
void HtmlRenderer::renderInlinedHtml(const HtmlTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    assert(node->htmlNodeType() == HtmlTreeNode::START_TAG_WITH_MATCHING_END_TAG ||
           node->hasChildren() == false);

    switch (node->htmlNodeType()) {
    case HtmlTreeNode::START_TAG_WITH_MATCHING_END_TAG:
        outputDevice()->write(node->startTagText());
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write(node->endTagText());
        break;
    case HtmlTreeNode::EMPTY_TAG:
    case HtmlTreeNode::START_TAG_ONLY:
    case HtmlTreeNode::END_TAG_ONLY:
    case HtmlTreeNode::COMMENT:
        outputDevice()->write(node->fullHtmlText());
        break;
    case HtmlTreeNode::VERBATIM_HTML_CHUNK:
        outputDevice()->write(node->fullHtmlText());
        break;
    default:
        assert(false);
    }
}
示例#4
0
void HtmlRenderer::renderBlockquote(const BlockquoteTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    renderIndentation(ancestorNodes->size());
    outputDevice()->write("<blockquote>\n", 13);
    renderChildNodesOf(node, ancestorNodes);
    renderIndentation(ancestorNodes->size());
    outputDevice()->write("</blockquote>\n", 14);
}
示例#5
0
void HtmlRenderer::renderCodeSpan(const CodeSpanTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    UNUSED_ARG(ancestorNodes);

    if (node == 0) {
        return;
    }

    assert(node->hasChildren() == false);

    outputDevice()->write("<code>", 6);
    HtmlTextRenderer::renderCode(outputDevice(), node->textContent().trimmed());
    outputDevice()->write("</code>", 7);
}
示例#6
0
void HtmlRenderer::renderCodeBlock(const CodeBlockTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    UNUSED_ARG(ancestorNodes);

    if (node == 0) {
        return;
    }

    assert(node->hasChildren() == false);

    outputDevice()->write("<pre><code>", 11);
    HtmlTextRenderer::renderCode(outputDevice(), node->textContent());
    outputDevice()->write("</code></pre>\n", 14);
}
示例#7
0
void TreeRenderer::renderTreePrefix(const VfmdElementTreeNodeStack *ancestorNodes, const char *followup)
{
    unsigned int ancestorsCount = ancestorNodes->size();
    for (unsigned int i = 0; i < ancestorsCount; i++) {
        const VfmdElementTreeNode *ancestorNode = ancestorNodes->nodeAt(i);
        if (ancestorNode->hasNext()) {
            outputDevice()->write("|  ");
        } else {
            outputDevice()->write("   ");
        }
    }
    if (followup) {
        outputDevice()->write(followup);
    }
}
示例#8
0
void MidiPlugin::openOutput(quint32 output)
{
    qDebug() << "MIDI plugin open output: " << output;

    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
        dev->open();
}
示例#9
0
void HtmlRenderer::renderSetextHeader(const SetextHeaderTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    renderIndentation(ancestorNodes->size());

    int headingLevel = node->headingLevel();
    assert(headingLevel == 1 || headingLevel == 2);

    if (headingLevel == 1 || headingLevel == 2) {
        outputDevice()->write((headingLevel == 1)? "<h1>" : "<h2>");
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write((headingLevel == 1)? "</h1>\n" : "</h2>\n");
    }
}
示例#10
0
void MidiPlugin::writeUniverse(quint32 universe, quint32 output, const QByteArray &data)
{
    Q_UNUSED(universe)

    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
        dev->writeUniverse(data);
}
示例#11
0
void MidiPlugin::sendSysEx(quint32 output, const QByteArray &data)
{
    qDebug() << "sendSysEx data: " << data;

    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
        dev->writeSysEx(data);
}
示例#12
0
void HtmlRenderer::renderOrderedList(const OrderedListTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    outputDevice()->write('\n');
    renderIndentation(ancestorNodes->size());

    VfmdByteArray startingNumber = node->startingNumber();
    if (startingNumber.size() > 0 && !startingNumber.isEqualTo("1")) {
        outputDevice()->write("<ol start=\"", 11);
        outputDevice()->write(startingNumber);
        outputDevice()->write("\">\n", 3);
    } else {
        outputDevice()->write("<ol>\n", 5);
    }

    if (node->hasChildren()) {
        ancestorNodes->push(node);

        for (const VfmdElementTreeNode *childNode = node->firstChildNode();
             childNode != 0;
             childNode = childNode->nextNode()) {

            const OrderedListItemTreeNode *listItemNode = dynamic_cast<const OrderedListItemTreeNode *>(childNode);
            if (listItemNode) {
                renderIndentation(ancestorNodes->size());
                bool containsASingleParagraph = (listItemNode->firstChildNode()->elementType() == VfmdConstants::PARAGRAPH_ELEMENT &&
                                                 listItemNode->firstChildNode()->nextNode() == 0);
                if (containsASingleParagraph) {
                    outputDevice()->write("<li>", 4);
                } else {
                    outputDevice()->write("<li>\n", 5);
                }
                renderChildNodesOf(listItemNode, ancestorNodes);
                if (!containsASingleParagraph) {
                    renderIndentation(ancestorNodes->size());
                }
                outputDevice()->write("</li>\n", 6);
            }

        }

        const VfmdElementTreeNode *poppedNode = ancestorNodes->pop();
        assert(poppedNode == node);
    }

    renderIndentation(ancestorNodes->size());
    outputDevice()->write("</ol>\n", 6);
}
示例#13
0
void MidiPlugin::closeOutput(quint32 output)
{
    qDebug() << Q_FUNC_INFO;

    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
        dev->close();
}
示例#14
0
void MidiPlugin::sendFeedBack(quint32 output, quint32 channel, uchar value)
{
    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
    {
        qDebug() << "[sendFeedBack] Channel: " << channel << ", value: " << value;
        dev->writeChannel(channel, value);
    }
}
示例#15
0
void HtmlRenderer::renderHorizontalRule(const HorizontalRuleTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    assert(node->hasChildren() == false);

    renderIndentation(ancestorNodes->size());
    outputDevice()->write(isSelfClosingVoidTagsEnabled()? "<hr />\n" : "<hr>\n");
}
示例#16
0
void HtmlRenderer::renderLink(const LinkTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    if (node->refType() == LinkTreeNode::NO_REF) {
        // Inline link like "[link](url)"
        renderLinkOpenTag(node->url(), node->title(), outputDevice());
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write("</a>", 4);
    } else {
        // Reference link like "[link-ref]" or "[link][ref]" or "[link-ref][]"
        const VfmdLinkRefMap *linkRefMap = node->linkRefMap();
        VfmdByteArray refId = node->refIdText().simplified().toLowerCase();
        if ((refId.size() > 0) && (linkRefMap->hasData(refId))) {
            // We found a definition for this ref id
            VfmdByteArray linkUrl = linkRefMap->linkUrl(refId);
            VfmdByteArray linkTitle = linkRefMap->linkTitle(refId);
            renderLinkOpenTag(linkUrl, linkTitle, outputDevice());
            renderChildNodesOf(node, ancestorNodes);
            outputDevice()->write("</a>", 4);
        } else {
            // We didn't find a definition for this ref id
            outputDevice()->write('[');
            renderChildNodesOf(node, ancestorNodes);
            HtmlTextRenderer::renderText(outputDevice(), node->closeTagText(),
                                         isSelfClosingVoidTagsEnabled(),
                                         isLineBreakOnNewlinesEnabled());
        }
    }
}
示例#17
0
void HtmlRenderer::renderTextSpan(const TextSpanTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    UNUSED_ARG(ancestorNodes);

    if (node == 0) {
        return;
    }

    assert(node->hasChildren() == false);

    HtmlTextRenderer::renderText(outputDevice(), node->textContent(),
                                 isSelfClosingVoidTagsEnabled(),
                                 isLineBreakOnNewlinesEnabled());
}
示例#18
0
void MidiPlugin::sendFeedBack(quint32 output, quint32 channel, uchar value, const QString &)
{
    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
    {
        qDebug() << "[sendFeedBack] Channel:" << channel << ", value:" << value;
        uchar cmd = 0;
        uchar data1 = 0, data2 = 0;
        if (QLCMIDIProtocol::feedbackToMidi(channel, value, dev->midiChannel(),
                                        &cmd, &data1, &data2) == true)
        {
            qDebug() << Q_FUNC_INFO << "cmd:" << cmd << "data1:" << data1 << "data2:" << data2;
            dev->writeFeedback(cmd, data1, data2);
        }
    }
}
示例#19
0
void MidiPlugin::openOutput(quint32 output)
{
    qDebug() << "MIDI plugin open output: " << output;

    MidiOutputDevice* dev = outputDevice(output);

    if (dev == NULL)
        return;

    dev->open();

    if (dev->midiTemplateName() != "")
    {
        qDebug() << "Opening device with Midi template: " << dev->midiTemplateName();

        MidiTemplate* templ = midiTemplate(dev->midiTemplateName());

        if (templ != NULL)
            sendSysEx(output, templ->initMessage());
    }
}
示例#20
0
void HtmlRenderer::renderAutomaticLink(const AutomaticLinkTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    assert(node->hasChildren() == false);

    outputDevice()->write("<a href=\"", 9);
    if (node->urlType() == AutomaticLinkTreeNode::MAIL_URL_WITHOUT_MAILTO) {
        outputDevice()->write("mailto:", 7);
    }
    HtmlTextRenderer::renderURL(outputDevice(), node->url());
    outputDevice()->write("\">", 2);
    HtmlTextRenderer::renderURLAsText(outputDevice(), node->url());
    outputDevice()->write("</a>", 4);
}
示例#21
0
QString MidiPlugin::outputInfo(quint32 output)
{
    qDebug() << Q_FUNC_INFO;

    QString str;

    if (output == QLCIOPlugin::invalidLine())
    {
        str += QString("<BR><B>%1</B>").arg(tr("No output support available."));
        return str;
    }

    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
    {
        QString status;
        str += QString("<H3>%1 %2</H3>").arg(tr("Output")).arg(outputs()[output]);
        str += QString("<P>");
        if (dev->isOpen() == true)
            status = tr("Open");
        else
            status = tr("Not Open");
        str += QString("%1: %2").arg(tr("Status")).arg(status);
        str += QString("</P>");
    }
    else
    {
        if (output < (quint32)outputs().length())
            str += QString("<H3>%1 %2</H3>").arg(tr("Invalid Output")).arg(outputs()[output]);
    }

    str += QString("</BODY>");
    str += QString("</HTML>");

    return str;
}
示例#22
0
void HtmlRenderer::renderUnorderedList(const UnorderedListTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    outputDevice()->write('\n');
    renderIndentation(ancestorNodes->size());
    outputDevice()->write("<ul>\n", 5);

    if (node->hasChildren()) {
        ancestorNodes->push(node);

        for (const VfmdElementTreeNode *childNode = node->firstChildNode();
             childNode != 0;
             childNode = childNode->nextNode()) {

            const UnorderedListItemTreeNode *listItemNode = dynamic_cast<const UnorderedListItemTreeNode *>(childNode);
            if (listItemNode) {
                renderIndentation(ancestorNodes->size());
                bool containsASingleParagraph = (listItemNode->firstChildNode()->elementType() == VfmdConstants::PARAGRAPH_ELEMENT &&
                                                 listItemNode->firstChildNode()->nextNode() == 0);
                if (containsASingleParagraph) {
                    outputDevice()->write("<li>", 4);
                } else {
                    outputDevice()->write("<li>\n", 5);
                }
                renderChildNodesOf(listItemNode, ancestorNodes);
                if (!containsASingleParagraph) {
                    renderIndentation(ancestorNodes->size());
                }
                outputDevice()->write("</li>\n", 6);
            }

        }

        const VfmdElementTreeNode *poppedNode = ancestorNodes->pop();
        assert(poppedNode == node);
    }

    renderIndentation(ancestorNodes->size());
    outputDevice()->write("</ul>\n", 6);
}
示例#23
0
void HtmlRenderer::renderEmphasis(const EmphasisTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    int repetitionCount = node->repetitionCount();
    if (repetitionCount == 1) {
        outputDevice()->write("<em>", 4);
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write("</em>", 5);
    } else if (repetitionCount == 2) {
        outputDevice()->write("<strong>", 8);
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write("</strong>", 9);
    } else if (repetitionCount > 2) {
        outputDevice()->write("<strong><em>", 12);
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write("</em></strong>", 14);
    }
}
示例#24
0
void HtmlRenderer::renderAtxHeader(const AtxHeaderTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    renderIndentation(ancestorNodes->size());

    int headingLevel = node->headingLevel();
    assert(headingLevel >= 1);
    assert(headingLevel <= 6);

    if (headingLevel >= 1 && headingLevel <= 6) {
        outputDevice()->write("<h", 2);
        outputDevice()->write('0' + headingLevel);
        outputDevice()->write('>');
        renderChildNodesOf(node, ancestorNodes);
        outputDevice()->write("</h", 3);
        outputDevice()->write('0' + headingLevel);
        outputDevice()->write(">\n");
    }
}
示例#25
0
void HtmlRenderer::renderParagraph(const ParagraphTreeNode *node, VfmdElementTreeNodeStack *ancestorNodes)
{
    if (node == 0) {
        return;
    }

    bool canEncloseContentInPTags = (node->shouldAvoidWrappingInHtmlPTag() == false);
    bool isSoleContentOfAListItem = false;
    bool isContainedInTopPackedListItem = false;
    bool isContainedInBottomPackedListItem = false;
    const VfmdElementTreeNode *parentNode = ancestorNodes->topNode();
    if (parentNode) {
        if (parentNode->elementType() == VfmdConstants::UNORDERED_LIST_ELEMENT) {
            const UnorderedListItemTreeNode *listItemNode = dynamic_cast<const UnorderedListItemTreeNode *>(parentNode);
            if (listItemNode) {
                isSoleContentOfAListItem = ((listItemNode->firstChildNode() == node) && (node->nextNode() == 0));
                isContainedInTopPackedListItem = listItemNode->isTopPacked();
                isContainedInBottomPackedListItem = listItemNode->isBottomPacked();
            }
        } else if (parentNode->elementType() == VfmdConstants::ORDERED_LIST_ELEMENT) {
            const OrderedListItemTreeNode *listItemNode = dynamic_cast<const OrderedListItemTreeNode *>(parentNode);
            if (listItemNode) {
                isSoleContentOfAListItem = ((listItemNode->firstChildNode() == node) && (node->nextNode() == 0));
                isContainedInTopPackedListItem = listItemNode->isTopPacked();
                isContainedInBottomPackedListItem = listItemNode->isBottomPacked();
            }
        }
    }

    if (canEncloseContentInPTags) {
        // If this paragraph is part of a list item, there are additional things to be
        // considered in deciding whether the content can be enclosed in p tags
        if (isContainedInTopPackedListItem) {
            bool firstBlockInParent = (parentNode && parentNode->firstChildNode() == node);
            if (firstBlockInParent) {
                canEncloseContentInPTags = false;
            }
        }
        if (isContainedInBottomPackedListItem) {
            bool secondBlockInParent = (parentNode && parentNode->firstChildNode() &&
                                        parentNode->firstChildNode()->nextNode() == node);
            bool lastBlockInParent = (parentNode && parentNode->lastChildNode() == node);
            if (lastBlockInParent && !secondBlockInParent) {
                canEncloseContentInPTags = false;
            }
        }
    }

    if (isSoleContentOfAListItem) {
        // The paragraph is going to be on the same line as the <li> tag.
        // Compact form.
        if (canEncloseContentInPTags) {
            outputDevice()->write("<p>", 3);
            renderChildNodesOf(node, ancestorNodes);
            outputDevice()->write("</p>", 4);
        } else {
            renderChildNodesOf(node, ancestorNodes);
        }
    } else {
        // Normal form.
        renderIndentation(ancestorNodes->size());
        if (canEncloseContentInPTags) {
            outputDevice()->write("<p>", 3);
            renderChildNodesOf(node, ancestorNodes);
            outputDevice()->write("</p>\n\n", 6);
        } else {
            renderChildNodesOf(node, ancestorNodes);
            outputDevice()->write("\n\n", 2);
        }
    }
}
示例#26
0
void PulseAudioSystem::eventCallback(pa_mainloop_api *api, pa_defer_event *) {
	api->defer_enable(pade, false);

	if (! bSourceDone || ! bSinkDone || ! bServerDone)
		return;

	AudioInputPtr ai = g.ai;
	AudioOutputPtr ao = g.ao;
	AudioInput *raw_ai = ai.get();
	AudioOutput *raw_ao = ao.get();
	PulseAudioInput *pai = dynamic_cast<PulseAudioInput *>(raw_ai);
	PulseAudioOutput *pao = dynamic_cast<PulseAudioOutput *>(raw_ao);

	if (raw_ao) {
		QString odev = outputDevice();
		pa_stream_state ost = pasOutput ? pa_stream_get_state(pasOutput) : PA_STREAM_TERMINATED;
		bool do_stop = false;
		bool do_start = false;

		if (! pao && (ost == PA_STREAM_READY)) {
			do_stop = true;
		} else if (pao) {
			switch (ost) {
				case PA_STREAM_TERMINATED: {
						if (pasOutput)
							pa_stream_unref(pasOutput);

						pa_sample_spec pss = qhSpecMap.value(odev);
						pa_channel_map pcm = qhChanMap.value(odev);
						if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
							pss.format = PA_SAMPLE_FLOAT32NE;
						if (pss.rate == 0)
							pss.rate = SAMPLE_RATE;
						if ((pss.channels == 0) || (! g.s.doPositionalAudio()))
							pss.channels = 1;

						pasOutput = pa_stream_new(pacContext, mumble_sink_input, &pss, (pss.channels == 1) ? NULL : &pcm);
						pa_stream_set_state_callback(pasOutput, stream_callback, this);
						pa_stream_set_write_callback(pasOutput, write_callback, this);
					}
				case PA_STREAM_UNCONNECTED:
					do_start = true;
					break;
				case PA_STREAM_READY: {
						if (g.s.iOutputDelay != iDelayCache) {
							do_stop = true;
						} else if (g.s.doPositionalAudio() != bPositionalCache) {
							do_stop = true;
						} else if (odev != qsOutputCache) {
							do_stop = true;
						}
						break;
					}
				default:
					break;
			}
		}
		if (do_stop) {
			qWarning("PulseAudio: Stopping output");
			pa_stream_disconnect(pasOutput);
			iSinkId = -1;
		} else if (do_start) {
			qWarning("PulseAudio: Starting output: %s", qPrintable(odev));
			pa_buffer_attr buff;
			const pa_sample_spec *pss = pa_stream_get_sample_spec(pasOutput);
			const size_t sampleSize = (pss->format == PA_SAMPLE_FLOAT32NE) ? sizeof(float) : sizeof(short);
			const unsigned int iBlockLen = ((pao->iFrameSize * pss->rate) / SAMPLE_RATE) * pss->channels * static_cast<unsigned int>(sampleSize);
			buff.tlength = iBlockLen * (g.s.iOutputDelay+1);
			buff.minreq = iBlockLen;
			buff.maxlength = -1;
			buff.prebuf = -1;
			buff.fragsize = iBlockLen;

			iDelayCache = g.s.iOutputDelay;
			bPositionalCache = g.s.doPositionalAudio();
			qsOutputCache = odev;

			pa_stream_connect_playback(pasOutput, qPrintable(odev), &buff, PA_STREAM_ADJUST_LATENCY, NULL, NULL);
			pa_context_get_sink_info_by_name(pacContext, qPrintable(odev), sink_info_callback, this);
		}
	}

	if (raw_ai) {
		QString idev = inputDevice();
		pa_stream_state ist = pasInput ? pa_stream_get_state(pasInput) : PA_STREAM_TERMINATED;
		bool do_stop = false;
		bool do_start = false;

		if (! pai && (ist == PA_STREAM_READY)) {
			do_stop = true;
		} else if (pai) {
			switch (ist) {
				case PA_STREAM_TERMINATED: {
						if (pasInput)
							pa_stream_unref(pasInput);

						pa_sample_spec pss = qhSpecMap.value(idev);
						if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
							pss.format = PA_SAMPLE_FLOAT32NE;
						if (pss.rate == 0)
							pss.rate = SAMPLE_RATE;
						pss.channels = 1;

						pasInput = pa_stream_new(pacContext, "Microphone", &pss, NULL);
						pa_stream_set_state_callback(pasInput, stream_callback, this);
						pa_stream_set_read_callback(pasInput, read_callback, this);
					}
				case PA_STREAM_UNCONNECTED:
					do_start = true;
					break;
				case PA_STREAM_READY: {
						if (idev != qsInputCache) {
							do_stop = true;
						}
						break;
					}
				default:
					break;
			}
		}
		if (do_stop) {
			qWarning("PulseAudio: Stopping input");
			pa_stream_disconnect(pasInput);
		} else if (do_start) {
			qWarning("PulseAudio: Starting input %s",qPrintable(idev));
			pa_buffer_attr buff;
			const pa_sample_spec *pss = pa_stream_get_sample_spec(pasInput);
			const size_t sampleSize = (pss->format == PA_SAMPLE_FLOAT32NE) ? sizeof(float) : sizeof(short);
			const unsigned int iBlockLen = ((pai->iFrameSize * pss->rate) / SAMPLE_RATE) * pss->channels * static_cast<unsigned int>(sampleSize);
			buff.tlength = iBlockLen;
			buff.minreq = iBlockLen;
			buff.maxlength = -1;
			buff.prebuf = -1;
			buff.fragsize = iBlockLen;

			qsInputCache = idev;

			pa_stream_connect_record(pasInput, qPrintable(idev), &buff, PA_STREAM_ADJUST_LATENCY);
		}
	}

	if (raw_ai) {
		QString odev = outputDevice();
		QString edev = qhEchoMap.value(odev);
		pa_stream_state est = pasSpeaker ? pa_stream_get_state(pasSpeaker) : PA_STREAM_TERMINATED;
		bool do_stop = false;
		bool do_start = false;

		if ((! pai || ! g.s.doEcho()) && (est == PA_STREAM_READY)) {
			do_stop = true;
		} else if (pai && g.s.doEcho()) {
			switch (est) {
				case PA_STREAM_TERMINATED: {
						if (pasSpeaker)
							pa_stream_unref(pasSpeaker);

						pa_sample_spec pss = qhSpecMap.value(edev);
						pa_channel_map pcm = qhChanMap.value(edev);
						if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
							pss.format = PA_SAMPLE_FLOAT32NE;
						if (pss.rate == 0)
							pss.rate = SAMPLE_RATE;
						if ((pss.channels == 0) || (! g.s.bEchoMulti))
							pss.channels = 1;

						pasSpeaker = pa_stream_new(pacContext, mumble_echo, &pss, (pss.channels == 1) ? NULL : &pcm);
						pa_stream_set_state_callback(pasSpeaker, stream_callback, this);
						pa_stream_set_read_callback(pasSpeaker, read_callback, this);
					}
				case PA_STREAM_UNCONNECTED:
					do_start = true;
					break;
				case PA_STREAM_READY: {
						if (g.s.bEchoMulti != bEchoMultiCache) {
							do_stop = true;
						} else if (edev != qsEchoCache) {
							do_stop = true;
						}
						break;
					}
				default:
					break;
			}
		}
		if (do_stop) {
			qWarning("PulseAudio: Stopping echo");
			pa_stream_disconnect(pasSpeaker);
		} else if (do_start) {
			qWarning("PulseAudio: Starting echo: %s", qPrintable(edev));
			pa_buffer_attr buff;
			const pa_sample_spec *pss = pa_stream_get_sample_spec(pasSpeaker);
			const size_t sampleSize = (pss->format == PA_SAMPLE_FLOAT32NE) ? sizeof(float) : sizeof(short);
			const unsigned int iBlockLen = ((pai->iFrameSize * pss->rate) / SAMPLE_RATE) * pss->channels * static_cast<unsigned int>(sampleSize);
			buff.tlength = iBlockLen;
			buff.minreq = iBlockLen;
			buff.maxlength = -1;
			buff.prebuf = -1;
			buff.fragsize = iBlockLen;

			bEchoMultiCache = g.s.bEchoMulti;
			qsEchoCache = edev;

			pa_stream_connect_record(pasSpeaker, qPrintable(edev), &buff, PA_STREAM_ADJUST_LATENCY);
		}
	}
}
示例#27
0
void HtmlRenderer::renderIndentation(int level)
{
    if (isIndentationEnabled()) {
        outputDevice()->write(' ', level * 2);
    }
}
示例#28
0
void MidiPlugin::writeUniverse(quint32 output, const QByteArray& universe)
{
    MidiOutputDevice* dev = outputDevice(output);
    if (dev != NULL)
        dev->writeUniverse(universe);
}
void MusicAudioRecorderWidget::createAudioOutput()
{
    QAudioDeviceInfo outputDevice(QAudioDeviceInfo::defaultOutputDevice());
    m_mpAudioOutputSound = new QAudioOutput(outputDevice, m_mFormatSound, this);
}
示例#30
0
void MidiEnumeratorPrivate::rescan()
{
    qDebug() << Q_FUNC_INFO;

    if (m_alsa == NULL)
        return;

    bool changed = false;
    QList <MidiOutputDevice*> destroyOutputs(m_outputDevices);
    QList <MidiInputDevice*> destroyInputs(m_inputDevices);

    snd_seq_client_info_t* clientInfo = NULL;
    snd_seq_client_info_alloca(&clientInfo);

    snd_seq_port_info_t* portInfo = NULL;
    snd_seq_port_info_alloca(&portInfo);

    snd_seq_client_info_set_client(clientInfo, 0);
    while (snd_seq_query_next_client(m_alsa, clientInfo) == 0)
    {
        /* Get the client ID */
        int client = snd_seq_client_info_get_client(clientInfo);

        /* Ignore our own client */
        if (m_address->client == client)
            continue;

        /* Go thru all available ports in the client */
        snd_seq_port_info_set_client(portInfo, client);
        snd_seq_port_info_set_port(portInfo, -1);
        while (snd_seq_query_next_port(m_alsa, portInfo) == 0)
        {
            const snd_seq_addr_t* address = snd_seq_port_info_get_addr(portInfo);
            if (address == NULL)
                continue;

            uint caps = snd_seq_port_info_get_capability(portInfo);
            if (caps & SND_SEQ_PORT_CAP_READ)
            {
                // Don't expose own ports
                QString name = AlsaMidiUtil::extractName(m_alsa, address);
                if (name.contains("__QLC__") == true)
                    continue;

                QVariant uid = AlsaMidiUtil::addressToVariant(address);
                MidiInputDevice* dev = inputDevice(uid);
                if (dev == NULL)
                {
                    AlsaMidiInputDevice* dev = new AlsaMidiInputDevice(
                            uid, name, address, m_alsa, m_inputThread, this);
                    m_inputDevices << dev;
                    changed = true;
                }
                else
                {
                    destroyInputs.removeAll(dev);
                }
            }

            if (caps & SND_SEQ_PORT_CAP_WRITE)
            {
                // Don't expose own ports
                QString name = AlsaMidiUtil::extractName(m_alsa, address);
                if (name.contains("__QLC__") == true)
                    continue;

                QVariant uid = AlsaMidiUtil::addressToVariant(address);
                MidiOutputDevice* dev = outputDevice(uid);
                if (dev == NULL)
                {
                    AlsaMidiOutputDevice* dev = new AlsaMidiOutputDevice(
                                    uid, name, address, m_alsa, m_address, this);
                    m_outputDevices << dev;
                    changed = true;
                }
                else
                {
                    destroyOutputs.removeAll(dev);
                }
            }
        }
    }

    foreach (MidiOutputDevice* dev, destroyOutputs)
    {
        m_outputDevices.removeAll(dev);
        delete dev;
        changed = true;
    }