00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "WAVAudioFileServerMediaSubsession.hh"
00023 #include "WAVAudioFileSource.hh"
00024 #include "uLawAudioFilter.hh"
00025 #include "SimpleRTPSink.hh"
00026
00027 WAVAudioFileServerMediaSubsession* WAVAudioFileServerMediaSubsession
00028 ::createNew(UsageEnvironment& env, char const* fileName, Boolean reuseFirstSource,
00029 Boolean convertToULaw) {
00030 return new WAVAudioFileServerMediaSubsession(env, fileName,
00031 reuseFirstSource, convertToULaw);
00032 }
00033
00034 WAVAudioFileServerMediaSubsession
00035 ::WAVAudioFileServerMediaSubsession(UsageEnvironment& env, char const* fileName,
00036 Boolean reuseFirstSource, Boolean convertToULaw)
00037 : FileServerMediaSubsession(env, fileName, reuseFirstSource),
00038 fConvertToULaw(convertToULaw) {
00039 }
00040
00041 WAVAudioFileServerMediaSubsession
00042 ::~WAVAudioFileServerMediaSubsession() {
00043 }
00044
00045 void WAVAudioFileServerMediaSubsession
00046 ::seekStreamSource(FramedSource* inputSource, float seekNPT) {
00047 WAVAudioFileSource* wavSource;
00048 if (fBitsPerSample == 16) {
00049
00050 wavSource = (WAVAudioFileSource*)(((FramedFilter*)inputSource)->inputSource());
00051 } else {
00052
00053 wavSource = (WAVAudioFileSource*)inputSource;
00054 }
00055
00056 unsigned seekSampleNumber = (unsigned)(seekNPT*fSamplingFrequency);
00057 unsigned seekByteNumber = (seekSampleNumber*fNumChannels*fBitsPerSample)/8;
00058
00059 wavSource->seekToPCMByte(seekByteNumber);
00060 }
00061
00062 void WAVAudioFileServerMediaSubsession
00063 ::setStreamSourceScale(FramedSource* inputSource, float scale) {
00064 int iScale = (int)scale;
00065 WAVAudioFileSource* wavSource;
00066 if (fBitsPerSample == 16) {
00067
00068 wavSource = (WAVAudioFileSource*)(((FramedFilter*)inputSource)->inputSource());
00069 } else {
00070
00071 wavSource = (WAVAudioFileSource*)inputSource;
00072 }
00073
00074 wavSource->setScaleFactor(iScale);
00075 }
00076
00077 FramedSource* WAVAudioFileServerMediaSubsession
00078 ::createNewStreamSource(unsigned , unsigned& estBitrate) {
00079 FramedSource* resultSource = NULL;
00080 do {
00081 WAVAudioFileSource* wavSource
00082 = WAVAudioFileSource::createNew(envir(), fFileName);
00083 if (wavSource == NULL) break;
00084
00085
00086 fBitsPerSample = wavSource->bitsPerSample();
00087 if (fBitsPerSample != 8 && fBitsPerSample != 16) {
00088 envir() << "The input file contains " << fBitsPerSample
00089 << " bit-per-sample audio, which we don't handle\n";
00090 break;
00091 }
00092 fSamplingFrequency = wavSource->samplingFrequency();
00093 fNumChannels = wavSource->numChannels();
00094 unsigned bitsPerSecond
00095 = fSamplingFrequency*fBitsPerSample*fNumChannels;
00096
00097 fFileDuration = (float)((8.0*wavSource->numPCMBytes())
00098 /(fSamplingFrequency*fNumChannels*fBitsPerSample));
00099
00100
00101 if (fBitsPerSample == 16) {
00102
00103 if (fConvertToULaw) {
00104
00105
00106 resultSource
00107 = uLawFromPCMAudioSource::createNew(envir(), wavSource, 1);
00108 bitsPerSecond /= 2;
00109 } else {
00110
00111 resultSource = EndianSwap16::createNew(envir(), wavSource);
00112 }
00113 } else {
00114
00115 resultSource = wavSource;
00116 }
00117
00118 estBitrate = (bitsPerSecond+500)/1000;
00119 return resultSource;
00120 } while (0);
00121
00122
00123 Medium::close(resultSource);
00124 return NULL;
00125 }
00126
00127 RTPSink* WAVAudioFileServerMediaSubsession
00128 ::createNewRTPSink(Groupsock* rtpGroupsock,
00129 unsigned char rtpPayloadTypeIfDynamic,
00130 FramedSource* ) {
00131 do {
00132 char* mimeType;
00133 unsigned char payloadFormatCode;
00134 if (fBitsPerSample == 16) {
00135 if (fConvertToULaw) {
00136 mimeType = "PCMU";
00137 if (fSamplingFrequency == 8000 && fNumChannels == 1) {
00138 payloadFormatCode = 0;
00139 } else {
00140 payloadFormatCode = rtpPayloadTypeIfDynamic;
00141 }
00142 } else {
00143 mimeType = "L16";
00144 if (fSamplingFrequency == 44100 && fNumChannels == 2) {
00145 payloadFormatCode = 10;
00146 } else if (fSamplingFrequency == 44100 && fNumChannels == 1) {
00147 payloadFormatCode = 11;
00148 } else {
00149 payloadFormatCode = rtpPayloadTypeIfDynamic;
00150 }
00151 }
00152 } else {
00153 mimeType = "L8";
00154 payloadFormatCode = rtpPayloadTypeIfDynamic;
00155 }
00156
00157 return SimpleRTPSink::createNew(envir(), rtpGroupsock,
00158 payloadFormatCode, fSamplingFrequency,
00159 "audio", mimeType, fNumChannels);
00160 } while (0);
00161
00162
00163 return NULL;
00164 }
00165
00166 void WAVAudioFileServerMediaSubsession::testScaleFactor(float& scale) {
00167 if (fFileDuration <= 0.0) {
00168
00169
00170 scale = 1;
00171 } else {
00172
00173 int iScale = scale < 0.0 ? (int)(scale - 0.5) : (int)(scale + 0.5);
00174 if (iScale == 0) iScale = 1;
00175 scale = (float)iScale;
00176 }
00177 }
00178
00179 float WAVAudioFileServerMediaSubsession::duration() const {
00180 return fFileDuration;
00181 }