繁体   English   中英

套接字上的音频c ++

[英]Audio over socket c++

我正在使用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连接器。

数据格式只是您的应用程序对待它们的方式。 毕竟,您通过套接字发送原始字节。 您可以随心所欲

Int16 data;
const char* pBytesOfData = (const char*) &data;
int size = sizeof (Int16);

send( socket, pBytesOfdata, size, flags);

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

您还可以查看简化序列化的库: Boost.AsioBoost.Serialization

首先,您需要创建并绑定套接字。 然后,您必须使用套接字API将“样本”中存储的数据发送给另一个对等方。 为了使用套接字API发送数据,您需要将此数据转换为char *。 由于套接字的发送API需要输入数据,因此您需要以char *形式发送。 有关发送的更多信息,您可以通过链接。 这是用于Windows。 对于Unix,您可以查看有关unix的send API的手册页。

Int16 *是一个指针。 您获得的样本还应该具有关联的长度。 您的数据可能在以下地址之间: [samples, samples + length) (其中samples是第一个样本的地址)。

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

  • 打开插座
  • 循环
    • 从麦克风获取样本
    • 通过套接字传输数据

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM