簡體   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