【问题标题】:Audio over socket c++套接字c ++上的音频
【发布时间】:2014-10-05 13:11:54
【问题描述】:

我正在使用SFML 从我的麦克风捕获一些音频。 数据存储在 Int16* 类型的样本中。

Int16* samples;

我的问题是。我应该如何处理这些样本以通过套接字将其流式传输以在另一个地方播放?我问的是数据类型。我需要将此 Int16 数组转换为另一种类型吗?或者我可以直接发送这个 Int16* 吗?

编辑

void BroadcastRecorder::loadBufferFromSamples()
{
    //m_samples is of type vector<Int16*>
    if (!m_samples.empty()){
        m_buffer.loadFromSamples(&m_samples[0], m_samples.size(), 1, getSampleRate());
        m_samples.clear();
    }
}

void Broadcaster::Send()
{
    //load the buffer with the samples
    if(!m_recorder->empty()){
        m_recorder->loadBufferFromSamples();
        const sf::SoundBuffer& buffer = m_recorder->getBuffer();

        size_t dataLength = m_recorder->GetSamplesSize();

        wxSocketClient * socket = new wxSocketClient(wxSOCKET_NOWAIT);
        socket->Notify(false);

        // ------------- DATA----------------------
        wxString data = "";
        wxString strToPrepend(_("--myboundary\r\nContent-Type: audio/wav\r\n"));
        wxString strToAppend(_("\r\n--myboundary\r\n"));

        // ------------- HEADER -----------------------
        wxString header = "";

        header.append("POST ");
        header.append("/cgi-bin/operator/transmit");
        header.append(" HTTP/1.0\r\n");
        header.append("Content-Type: multipart/form-data; boundary=--myboundary\r\n");
        header.append("Content-Length: " + wxString::Format(wxT("%i"),(dataLength + strToPrepend.Len() + strToAppend.Len()) ) + "\r\n");
        header.append("Authorization: Basic keykeykeykey\r\n");
        header.append("\r\n");

        //-------------- CONNECTION ---------------
        wxString host = _("192.168.50.11");
        wxIPV4address * address = new wxIPV4address();
        address->Hostname(host);
        address->Service(8084);

        if (socket->Connect(*address)){
            //Write header
            socket->Write(header.c_str(),header.Len());
            //Write data
            socket->Write(strToPrepend.c_str(),strToPrepend.Len());
            const sf::Int16* samples = buffer.getSamples();

            const char* bytesData = reinterpret_cast<const char*>(samples);

            socket->Write(bytesData,dataLength);

            socket->Write(strToAppend.c_str(),strToAppend.Len());

            socket->Close();
        }

        delete socket;
        delete address;
    }
}

我只在间隙之间听到一些噪音。

顺便说一句。音频正在发送到 IP 摄像机 p2 连接器。

【问题讨论】:

    标签: c++ sockets audio stream sfml


    【解决方案1】:

    数据格式就是您的应用程序处理它们的方式。毕竟,您通过套接字发送原始字节。你可以随心所欲地做到这一点

    Int16 data;
    const char* pBytesOfData = (const char*) &data;
    int size = sizeof (Int16);
    
    send( socket, pBytesOfdata, size, flags);
    

    当字节到达第二端时,由您来正确解释它们。可能您会再次将它们视为 Int16。您需要有一个协议(常见的通信方式)才能正确执行(可能在传输开始时发送数据的大小等)。

    您还可以查看易于使用的库serializationBoost.AsioBoost.Serialization

    【讨论】:

    • 感谢您的回复。就我而言,我有一个 Int16* 并且需要立即发送这个数组,可以将这个 (Int16*) 转换为 (const char*) 吗?
    • 这取决于上下文 - 在这种情况下是的,没关系,试试
    • 有点用。但我得到的只是噪音和它们之间的差距。这是通过套接字流式传输音频的最佳方法吗?请看我上次的编辑。
    • @RafaelTSCS 所以你应该接受答案。至于你的问题,见stackoverflow.com/a/7550258/1141471
    【解决方案2】:

    首先,您需要创建并绑定一个套接字。然后,您必须使用套接字 API 将存储在“样本”中的数据发送到另一个对等方。要使用套接字 API 发送数据,您需要将此数据转换为 char*。由于套接字的发送 API 需要输入您需要作为 char* 发送的数据。有关发送的更多信息,您可以通过this 链接。这是针对窗户的。对于 Unix,您可以查看 manpage 以了解用于 unix 的发送 API。

    【讨论】:

      【解决方案3】:

      Int16* 是一个指针。你得到的样本也应该有一个相关的长度。您的数据可能位于以下地址之间:[samples, samples + length)(其中samples 是第一个样本的地址)。

      远程播放示例(实际代码取决于您使用的 API):

      • 打开套接字
      • 在循环中
        • 从您的麦克风中获取样本
        • 通过套接字传输数据

      在服务器上,您必须循环读取样本并将它们发送到您使用的任何声音输出 API。

      【讨论】:

        【解决方案4】:

        套接字使用字节,所以最后你将发送字节。只要您在接收端解释这些字节的方式与您发送的数据相匹配,您就可以在这些字节中发送您想要的任何内容。

        在这种情况下,直接发送样本而不进行转换似乎是最简单的事情,但您可能需要先发送样本的大小,很可能是固定长度格式,例如:

        [size on 4 bytes][sample on `size` bytes]
        []   []   []   [][]  []   []  []  []   []
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-06-05
          • 2011-07-28
          • 2020-09-23
          • 2012-05-16
          • 1970-01-01
          • 2021-09-26
          • 2013-09-07
          • 1970-01-01
          相关资源
          最近更新 更多