Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RTPAVProfileSampleBasedAudioSender Class Reference

#include <RTPAVProfileSampleBasedAudioSender.h>

Inheritance diagram for RTPAVProfileSampleBasedAudioSender:

RTPPayloadSender RTPAVProfilePayload10Sender List of all members.

Detailed Description

The class RTPAVProfileSampleBasedAudioSender is a base class for modules sending sample based audio as defined in the RTP audio/video profile. For reading audio files it used libaudiofile. Subclasses must provide a method initialize() to set parameters like sampling rate, sample width and number of channels.


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


Member Function Documentation

void RTPAVProfileSampleBasedAudioSender::closeSourceFile  )  [protected, virtual]
 

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 };

void RTPAVProfileSampleBasedAudioSender::initializeSenderModule RTPInnerPacket  )  [protected, virtual]
 

Called when this sender module receives a message initializeSenderModule.

Reimplemented from RTPPayloadSender.

00029                                                                                     {
00030     RTPPayloadSender::initializeSenderModule(rinp);
00031     _startTime = simTime();
00032 };

void RTPAVProfileSampleBasedAudioSender::openSourceFile const char *  fileName  )  [protected, virtual]
 

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 };

void RTPAVProfileSampleBasedAudioSender::play  )  [protected, virtual]
 

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 };

void RTPAVProfileSampleBasedAudioSender::seekByte int  position  )  [protected, virtual]
 

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 };

void RTPAVProfileSampleBasedAudioSender::seekTime simtime_t  moment  )  [protected, virtual]
 

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 };

bool RTPAVProfileSampleBasedAudioSender::sendPacket  )  [protected, virtual]
 

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 };

void RTPAVProfileSampleBasedAudioSender::stop  )  [protected, virtual]
 

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 };


Member Data Documentation

AFfilehandle RTPAVProfileSampleBasedAudioSender::_audioFile [protected]
 

File handle for the audio file.

int RTPAVProfileSampleBasedAudioSender::_numberOfChannels [protected]
 

The number of different audio channels. Must be set by subclasses in initialize().

int RTPAVProfileSampleBasedAudioSender::_sampleWidth [protected]
 

The width of a sample of one channel in bits. Possibly values are 8, 16 and 24. Must be set by subclasses in initialize().

int RTPAVProfileSampleBasedAudioSender::_samplingRate [protected]
 

The sampling rate of the audio. Must be set by subclasses in initialize().

simtime_t RTPAVProfileSampleBasedAudioSender::_startTime [protected]
 

The time this sender module got initialized. Used to calculate time stamps.


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:24 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1