I'm working on a personal project where the iPhone connects to a server-type application running on a Mac. The iPhone send and receives textual/ASCII data via standard sockets. I now need to stream the microphone from the Mac to the iPhone. I've done some work with AudioServices before but wanted to check my thoughts here before getting too deep.
我正在做一个个人项目,在这个项目中,iPhone连接到一个运行在Mac上的服务器类型应用程序,iPhone通过标准套接字发送和接收文本/ASCII数据。我现在需要把麦克风从Mac上传到iPhone上。我以前做过一些音频服务的工作,但想在深入之前检查一下我的想法。
I'm thinking I can:
1. Create an Audio Queue in the standard Cocoa application on the Mac.
2. In my Audio Queue Callback function, rather than writing it to a file, write it to another socket I open for audio streaming.
3. On the iPhone, receive the raw sampled/encoded audio data from the TCP stream and dump it into an Audio Queue Player which outputs to headphone/speaker.
我想我可以:1。在Mac上的标准Cocoa应用程序中创建一个音频队列。在我的音频队列回调函数中,不要将其写入文件,而是将其写入另一个我打开的用于音频流的套接字中。3所示。在iPhone上,接收来自TCP流的原始采样/编码音频数据,并将其转储到音频队列播放器中,该播放器将输出到耳机/扬声器。
I know this is no small task and I've greatly simplified what I need to do but could it be as easy as that?
我知道这不是一个小任务,我已经大大简化了我需要做的事情,但它能像那样简单吗?
Thanks for any help you can provide,
Stateful
谢谢您提供的任何帮助,有状态的
1 个解决方案
#1
2
This looks broadly sensible, but you'll almost certainly need to do a few more things:
这看起来很合理,但你几乎肯定需要做更多的事情:
- Buffering. On the "recording" end, you probably don't want to block the audio queue if the buffer is full. On the "playback" end, I don't think you can just pass buffers into the queue (IIRC you'll need to buffer it until you get a callback).
- 缓冲。在“录制”端,如果缓冲区已满,您可能不想阻塞音频队列。在“回放”端,我不认为您可以将缓冲区传递到队列中(IIRC在得到回调之前,您需要对它进行缓冲区)。
- Concurrency. I'm pretty sure AQ callbacks happen on their own thread, so you'll need some sort of locking/barriers around your buffer accesses.
- 并发性。我很确定AQ回调发生在它们自己的线程上,因此您需要在缓冲区访问周围设置某种锁/屏障。
- Buffer pools, if memory allocation ends up being a big overhead.
- 缓冲池,如果内存分配最终导致很大的开销。
- Compression. AQ might be able to give you "IMA4" frames (IMA ADPCM 4:1, or so); I'm not sure if it does hardware MP3 decompression on the iPhone.
- 压缩。AQ可以为您提供“IMA4”帧(IMA ADPCM 4:1,或其他);我不确定它是否在iPhone上做硬件MP3解压。
- Packetization, if e.g. you need to interleave voice chat with text chat.
- 分组化,例如,你需要用文本聊天的方式进行语音聊天。
- EDIT: Playback sync (or whatever you're supposed to call it). You need to be able to handle different effective audio clock rates, whether it's due to a change in latency or something else. Skype does it by changing playback speed (with pitch-correction).
- 编辑:回放同步(或者你应该叫它的任何东西)。您需要能够处理不同的有效音频时钟频率,无论是由于延迟的变化还是其他原因。Skype通过改变回放速度(带有点修正)来实现这一点。
- EDIT: Packet loss. You might be able to get away with using TCP over a short link, but that depends a lot on the quality of your wireless network. UDP is a minor pain to get right (especially if you have to detect an MTU hole).
- 编辑:包丢失。您可以通过一个短链接使用TCP,但是这在很大程度上取决于您的无线网络的质量。UDP是一种需要纠正的小麻烦(特别是如果你必须检测一个MTU孔)。
Depending on your data rates, it might be worthwhile going for the lower-level (BSD) socket API and potentially even using readv()/writev().
根据您的数据速率,使用较低级别(BSD)套接字API,甚至使用readv()/writev()可能都是值得的。
If all you want is an "online radio" service and you don't care about the protocol used, it might be easier to use AVPlayer/MPMoviePlayer to play audio from a URL instead. This involves implementing a server which speaks Apple's HTTP streaming protocol; I believe Apple has some sample code that does this.
如果您想要的只是“在线广播”服务,而不关心所使用的协议,那么使用AVPlayer/MPMoviePlayer从URL播放音频可能会更容易。这涉及到实现一个能说出苹果的HTTP流协议的服务器;我相信苹果有一些这样做的示例代码。
#1
2
This looks broadly sensible, but you'll almost certainly need to do a few more things:
这看起来很合理,但你几乎肯定需要做更多的事情:
- Buffering. On the "recording" end, you probably don't want to block the audio queue if the buffer is full. On the "playback" end, I don't think you can just pass buffers into the queue (IIRC you'll need to buffer it until you get a callback).
- 缓冲。在“录制”端,如果缓冲区已满,您可能不想阻塞音频队列。在“回放”端,我不认为您可以将缓冲区传递到队列中(IIRC在得到回调之前,您需要对它进行缓冲区)。
- Concurrency. I'm pretty sure AQ callbacks happen on their own thread, so you'll need some sort of locking/barriers around your buffer accesses.
- 并发性。我很确定AQ回调发生在它们自己的线程上,因此您需要在缓冲区访问周围设置某种锁/屏障。
- Buffer pools, if memory allocation ends up being a big overhead.
- 缓冲池,如果内存分配最终导致很大的开销。
- Compression. AQ might be able to give you "IMA4" frames (IMA ADPCM 4:1, or so); I'm not sure if it does hardware MP3 decompression on the iPhone.
- 压缩。AQ可以为您提供“IMA4”帧(IMA ADPCM 4:1,或其他);我不确定它是否在iPhone上做硬件MP3解压。
- Packetization, if e.g. you need to interleave voice chat with text chat.
- 分组化,例如,你需要用文本聊天的方式进行语音聊天。
- EDIT: Playback sync (or whatever you're supposed to call it). You need to be able to handle different effective audio clock rates, whether it's due to a change in latency or something else. Skype does it by changing playback speed (with pitch-correction).
- 编辑:回放同步(或者你应该叫它的任何东西)。您需要能够处理不同的有效音频时钟频率,无论是由于延迟的变化还是其他原因。Skype通过改变回放速度(带有点修正)来实现这一点。
- EDIT: Packet loss. You might be able to get away with using TCP over a short link, but that depends a lot on the quality of your wireless network. UDP is a minor pain to get right (especially if you have to detect an MTU hole).
- 编辑:包丢失。您可以通过一个短链接使用TCP,但是这在很大程度上取决于您的无线网络的质量。UDP是一种需要纠正的小麻烦(特别是如果你必须检测一个MTU孔)。
Depending on your data rates, it might be worthwhile going for the lower-level (BSD) socket API and potentially even using readv()/writev().
根据您的数据速率,使用较低级别(BSD)套接字API,甚至使用readv()/writev()可能都是值得的。
If all you want is an "online radio" service and you don't care about the protocol used, it might be easier to use AVPlayer/MPMoviePlayer to play audio from a URL instead. This involves implementing a server which speaks Apple's HTTP streaming protocol; I believe Apple has some sample code that does this.
如果您想要的只是“在线广播”服务,而不关心所使用的协议,那么使用AVPlayer/MPMoviePlayer从URL播放音频可能会更容易。这涉及到实现一个能说出苹果的HTTP流协议的服务器;我相信苹果有一些这样做的示例代码。