#include <RTPAVProfileSampleBasedAudioSender.h>
Inheritance diagram for RTPAVProfileSampleBasedAudioSender:
Protected Member Functions | |
virtual void | initializeSenderModule (RTPInnerPacket *) |
virtual void | openSourceFile (const char *fileName) |
virtual void | closeSourceFile () |
virtual void | play () |
virtual void | stop () |
virtual void | seekTime (simtime_t moment) |
virtual void | seekByte (int position) |
virtual bool | sendPacket () |
Protected Attributes | |
AFfilehandle | _audioFile |
simtime_t | _startTime |
int | _samplingRate |
int | _sampleWidth |
int | _numberOfChannels |
|
This method is called by the destructor and closes the data file. Reimplemented from RTPPayloadSender. 00060 { 00061 int closeReturnValue = afCloseFile(_audioFile); 00062 if (closeReturnValue) { 00063 opp_error("sender module: error closing audio file"); 00064 } 00065 };
|
|
Called when this sender module receives a message initializeSenderModule. Reimplemented from RTPPayloadSender. 00029 { 00030 RTPPayloadSender::initializeSenderModule(rinp); 00031 _startTime = simTime(); 00032 };
|
|
This method is called by initializeSenderModule and opens the source data file as an inputFileStream stored in member variable _inputFileStream. Most data formats can use this method directly, but when using a library for a certain data format which offers an own open routine this method must be overwritten. Reimplemented from RTPPayloadSender. 00035 { 00036 _audioFile = afOpenFile(fileName, "r", 0); 00037 if (_audioFile == AF_NULL_FILEHANDLE) { 00038 opp_error("sender module: error opening audio file"); 00039 } 00040 else { 00041 if (_samplingRate != afGetRate(_audioFile, AF_DEFAULT_TRACK)) { 00042 opp_error("sender module: audio file has wrong sampling rate"); 00043 } 00044 else { 00045 int sampleFormat, sampleWidth; 00046 afGetSampleFormat(_audioFile, AF_DEFAULT_TRACK, &sampleFormat, &sampleWidth); 00047 if (_sampleWidth != sampleWidth) { 00048 opp_error("sender module: audio file has wrong sample width"); 00049 } 00050 else { 00051 if (_numberOfChannels != afGetChannels(_audioFile, AF_DEFAULT_TRACK)) { 00052 opp_error("sender module: audio file has wrong number of channels"); 00053 } 00054 } 00055 } 00056 } 00057 };
|
|
Starts data transmission. Every sender module must implement this method. Reimplemented from RTPPayloadSender. 00068 { 00069 if (_status == STOPPED) { 00070 _status = PLAYING; 00071 RTPSenderStatusMessage *rssm = new RTPSenderStatusMessage("PLAYING"); 00072 rssm->setStatus("PLAYING"); 00073 RTPInnerPacket *rinp = new RTPInnerPacket("senderStatus(PLAYING)"); 00074 rinp->senderModuleStatus(_ssrc, rssm); 00075 send(rinp, "toProfile"); 00076 sendPacket(); 00077 } 00078 else if (_status == PLAYING) { 00079 EV << "sender module: already playing" << endl; 00080 } 00081 };
|
|
When the data transmission is paused the current position is changed to this byte position (excluding file header). Implementation in sender modules is optional. Reimplemented from RTPPayloadSender. 00106 { 00107 if (_status = STOPPED) { 00108 int frameNumber = (int)(((float)position) / afGetFrameSize(_audioFile, AF_DEFAULT_TRACK, 0)); 00109 afSeekFrame(_audioFile, AF_DEFAULT_TRACK, frameNumber); 00110 RTPSenderStatusMessage *rssm = new RTPSenderStatusMessage("SEEKED"); 00111 rssm->setStatus("SEEKED"); 00112 RTPInnerPacket *rinp = new RTPInnerPacket("senderModuleStatus(SEEKED)"); 00113 rinp->senderModuleStatus(_ssrc, rssm); 00114 send(rinp, "toProfile"); 00115 } 00116 else { 00117 EV << "sender module: seeking not allowed while playing" << endl; 00118 }; 00119 };
|
|
When the data transmission is paused the current position is changed to this time (relative to start of file). Implementation in sender modules is optional. Reimplemented from RTPPayloadSender. 00090 { 00091 if (_status = STOPPED) { 00092 int frameNumber = (int)(moment * (float)_samplingRate); 00093 afSeekFrame(_audioFile, AF_DEFAULT_TRACK, frameNumber); 00094 RTPSenderStatusMessage *rssm = new RTPSenderStatusMessage("SEEKED"); 00095 rssm->setStatus("SEEKED"); 00096 RTPInnerPacket *rinp = new RTPInnerPacket("senderModuleStatus(SEEKED)"); 00097 rinp->senderModuleStatus(_ssrc, rssm); 00098 send(rinp, "toProfile"); 00099 } 00100 else { 00101 EV << "sender module: seeking not allowed while playing" << endl; 00102 }; 00103 };
|
|
This method gets called when one (or more) rtp data packets have to be sent. Subclasses must overwrite this method to do something useful. This implementation doesn't send packets it just returns Reimplemented from RTPPayloadSender. 00122 { 00123 RTPPacket *packet = new RTPPacket(); 00124 int bytesPerSample = (int)afGetFrameSize(_audioFile, AF_DEFAULT_TRACK, 0); 00125 int maxDataSize = _mtu - packet->headerLength(); 00126 maxDataSize = maxDataSize - (maxDataSize % bytesPerSample); 00127 00128 // AV profile: packetization interval for audio is 20 ms 00129 simtime_t packetizationInterval = 0.020; 00130 00131 int samplesPerPacketNeeded = (int)(((float)_samplingRate) * packetizationInterval); 00132 int samplesPerPacketPossible = maxDataSize / bytesPerSample; 00133 00134 int samplesInPacket; 00135 00136 // do samples for packetization interval fit into one packet? 00137 // if not put less samples in a packet 00138 if (samplesPerPacketPossible < samplesPerPacketNeeded) { 00139 packetizationInterval = ((float)samplesPerPacketPossible) / ((float)_samplingRate); 00140 samplesInPacket = samplesPerPacketPossible; 00141 } 00142 else { 00143 samplesInPacket = samplesPerPacketNeeded; 00144 } 00145 00146 int dataSize = samplesInPacket * bytesPerSample; 00147 00148 packet->setPayloadType(_payloadType); 00149 packet->setSequenceNumber(_sequenceNumber++); 00150 packet->setTimeStamp(_timeStampBase + (simTime() - _startTime) * (float)_samplingRate); 00151 packet->setSSRC(_ssrc); 00152 void *sampleData = malloc(dataSize); 00153 int samplesRead = afReadFrames(_audioFile, AF_DEFAULT_TRACK, sampleData, samplesInPacket); 00154 packet->addPar("data") = sampleData; 00155 packet->addLength(dataSize); 00156 RTPInnerPacket *rinp = new RTPInnerPacket("data()"); 00157 rinp->dataOut(packet); 00158 send(rinp, "toProfile"); 00159 if (afTellFrame(_audioFile, AF_DEFAULT_TRACK) >= afGetFrameCount(_audioFile, AF_DEFAULT_TRACK)) { 00160 return false; 00161 } 00162 else { 00163 _reminderMessage = new cMessage(); 00164 scheduleAt(simTime() + packetizationInterval, _reminderMessage); 00165 return true; 00166 }; 00167 };
|
|
This method stop data transmission and resets the sender module so that a following PLAY command would start the transmission at the beginning again. Reimplemented from RTPPayloadSender. 00084 { 00085 RTPPayloadSender::stop(); 00086 afSeekFrame(_audioFile, AF_DEFAULT_TRACK, 0); 00087 };
|
|
File handle for the audio file. |
|
The number of different audio channels. Must be set by subclasses in initialize(). |
|
The width of a sample of one channel in bits. Possibly values are 8, 16 and 24. Must be set by subclasses in initialize(). |
|
The sampling rate of the audio. Must be set by subclasses in initialize(). |
|
The time this sender module got initialized. Used to calculate time stamps. |