~ubuntu-branches/ubuntu/trusty/liblivemedia/trusty

« back to all changes in this revision

Viewing changes to testProgs/testWAVAudioStreamer.cpp

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2013-05-05 19:49:35 UTC
  • mfrom: (1.4.15) (11.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20130505194935-pyim0rda30k401ca
Tags: 2013.04.30-1
* Team upload.
* New upstream release.
* Upload to unstable after the Debian 7.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
along with this library; if not, write to the Free Software Foundation, Inc.,
14
14
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
15
15
**********/
16
 
// Copyright (c) 1996-2012, Live Networks, Inc.  All rights reserved
 
16
// Copyright (c) 1996-2013, Live Networks, Inc.  All rights reserved
17
17
// A test program that streams a WAV audio file via RTP/RTCP
18
18
// main program
19
19
 
58
58
 
59
59
void play() {
60
60
  // Open the file as a 'WAV' file:
61
 
  WAVAudioFileSource* pcmSource
62
 
    = WAVAudioFileSource::createNew(*env, inputFileName);
63
 
  if (pcmSource == NULL) {
 
61
  WAVAudioFileSource* wavSource = WAVAudioFileSource::createNew(*env, inputFileName);
 
62
  if (wavSource == NULL) {
64
63
    *env << "Unable to open file \"" << inputFileName
65
64
         << "\" as a WAV audio file source: "
66
65
         << env->getResultMsg() << "\n";
68
67
  }
69
68
 
70
69
  // Get attributes of the audio source:
71
 
  unsigned char const bitsPerSample = pcmSource->bitsPerSample();
72
 
  if (bitsPerSample != 8 && bitsPerSample !=  16) {
73
 
    *env << "The input file contains " << bitsPerSample
74
 
         << " bit-per-sample audio, which we don't handle\n";
 
70
  unsigned char audioFormat = wavSource->getAudioFormat();
 
71
  unsigned char const bitsPerSample = wavSource->bitsPerSample();
 
72
  // We handle only 4,8,16,20,24 bits-per-sample audio:
 
73
  if (bitsPerSample%4 != 0 || bitsPerSample < 4 || bitsPerSample > 24 || bitsPerSample == 12) {
 
74
    *env << "The input file contains " << bitsPerSample << " bit-per-sample audio, which we don't handle\n";
75
75
    exit(1);
76
76
  }
77
 
  sessionState.source = pcmSource;
78
 
  unsigned const samplingFrequency = pcmSource->samplingFrequency();
79
 
  unsigned char const numChannels = pcmSource->numChannels();
80
 
  unsigned bitsPerSecond
81
 
    = samplingFrequency*bitsPerSample*numChannels;
 
77
  unsigned const samplingFrequency = wavSource->samplingFrequency();
 
78
  unsigned char const numChannels = wavSource->numChannels();
 
79
  unsigned bitsPerSecond = samplingFrequency*bitsPerSample*numChannels;
82
80
  *env << "Audio source parameters:\n\t" << samplingFrequency << " Hz, ";
83
81
  *env << bitsPerSample << " bits-per-sample, ";
84
82
  *env << numChannels << " channels => ";
85
83
  *env << bitsPerSecond << " bits-per-second\n";
86
84
 
 
85
  char const* mimeType;
 
86
  unsigned char payloadFormatCode = 96; // by default, unless a static RTP payload type can be used
 
87
 
87
88
  // Add in any filter necessary to transform the data prior to streaming.
88
89
  // (This is where any audio compression would get added.)
89
 
  char const* mimeType;
90
 
  unsigned char payloadFormatCode;
91
 
  if (bitsPerSample == 16) {
 
90
  sessionState.source = wavSource; // by default
 
91
  if (audioFormat == WA_PCM) {
 
92
    if (bitsPerSample == 16) {
 
93
      // Note that samples in the WAV audio file are in little-endian order.
92
94
#ifdef CONVERT_TO_ULAW
93
 
    // Add a filter that converts from raw 16-bit PCM audio (in little-endian order)
94
 
    // to 8-bit u-law audio:
95
 
    sessionState.source
96
 
      = uLawFromPCMAudioSource::createNew(*env, pcmSource, 1/*little-endian*/);
97
 
    if (sessionState.source == NULL) {
98
 
      *env << "Unable to create a u-law filter from the PCM audio source: "
99
 
           << env->getResultMsg() << "\n";
100
 
      exit(1);
101
 
    }
102
 
    bitsPerSecond /= 2;
103
 
    mimeType = "PCMU";
104
 
    if (samplingFrequency == 8000 && numChannels == 1) {
105
 
      payloadFormatCode = 0; // a static RTP payload type
106
 
    } else {
107
 
      payloadFormatCode = 96; // a dynamic RTP payload type
108
 
    }
109
 
    *env << "Converting to 8-bit u-law audio for streaming => "
110
 
         << bitsPerSecond << " bits-per-second\n";
 
95
      // Add a filter that converts from raw 16-bit PCM audio (in little-endian order) to 8-bit u-law audio:
 
96
      sessionState.source = uLawFromPCMAudioSource::createNew(*env, wavSource, 1/*little-endian*/);
 
97
      if (sessionState.source == NULL) {
 
98
        *env << "Unable to create a u-law filter from the PCM audio source: " << env->getResultMsg() << "\n";
 
99
        exit(1);
 
100
      }
 
101
      *env << "Converting to 8-bit u-law audio for streaming => " << bitsPerSecond << " bits-per-second\n";
 
102
      bitsPerSecond /= 2;
 
103
      mimeType = "PCMU";
 
104
      if (samplingFrequency == 8000 && numChannels == 1) {
 
105
        payloadFormatCode = 0; // a static RTP payload type
 
106
      }
111
107
#else
112
 
    // The 16-bit samples in WAV files are in little-endian order.
113
 
    // Add a filter that converts them to network (i.e., big-endian) order:
114
 
    sessionState.source = EndianSwap16::createNew(*env, pcmSource);
115
 
    if (sessionState.source == NULL) {
116
 
      *env << "Unable to create a little->bit-endian order filter from the PCM audio source: "
117
 
           << env->getResultMsg() << "\n";
118
 
      exit(1);
119
 
    }
120
 
    mimeType = "L16";
121
 
    if (samplingFrequency == 44100 && numChannels == 2) {
122
 
      payloadFormatCode = 10; // a static RTP payload type
123
 
    } else if (samplingFrequency == 44100 && numChannels == 1) {
124
 
      payloadFormatCode = 11; // a static RTP payload type
125
 
    } else {
126
 
      payloadFormatCode = 96; // a dynamic RTP payload type
127
 
    }
128
 
    *env << "Converting to network byte order for streaming\n";
 
108
      // Add a filter that converts from little-endian to network (big-endian) order: 
 
109
      sessionState.source = EndianSwap16::createNew(*env, wavSource);
 
110
      if (sessionState.source == NULL) {
 
111
        *env << "Unable to create a little->bit-endian order filter from the PCM audio source: " << env->getResultMsg() << "\n";
 
112
        exit(1);
 
113
      }
 
114
      *env << "Converting to network byte order for streaming\n";
 
115
      mimeType = "L16";
 
116
      if (samplingFrequency == 44100 && numChannels == 2) {
 
117
        payloadFormatCode = 10; // a static RTP payload type
 
118
      } else if (samplingFrequency == 44100 && numChannels == 1) {
 
119
        payloadFormatCode = 11; // a static RTP payload type
 
120
      }
129
121
#endif
130
 
  } else { // bitsPerSample == 8
131
 
    // Don't do any transformation; send the 8-bit PCM data 'as is':
132
 
    mimeType = "L8";
133
 
    payloadFormatCode = 96; // a dynamic RTP payload type
 
122
    } else if (bitsPerSample == 20 || bitsPerSample == 24) {
 
123
      // Add a filter that converts from little-endian to network (big-endian) order: 
 
124
      sessionState.source = EndianSwap24::createNew(*env, wavSource);
 
125
      if (sessionState.source == NULL) {
 
126
        *env << "Unable to create a little->bit-endian order filter from the PCM audio source: " << env->getResultMsg() << "\n";
 
127
        exit(1);
 
128
      }
 
129
      *env << "Converting to network byte order for streaming\n";
 
130
      mimeType = bitsPerSample == 20 ? "L20" : "L24";
 
131
    } else { // bitsPerSample == 8 (we assume that bitsPerSample == 4 is only for WA_IMA_ADPCM)
 
132
      // Don't do any transformation; send the 8-bit PCM data 'as is':
 
133
      mimeType = "L8";
 
134
    }
 
135
  } else if (audioFormat == WA_PCMU) {
 
136
    mimeType = "PCMU";
 
137
    if (samplingFrequency == 8000 && numChannels == 1) {
 
138
      payloadFormatCode = 0; // a static RTP payload type                                                                          
 
139
    }
 
140
  } else if (audioFormat == WA_PCMA) {
 
141
    mimeType = "PCMA";
 
142
    if (samplingFrequency == 8000 && numChannels == 1) {
 
143
      payloadFormatCode = 8; // a static RTP payload type                                                                          
 
144
    } 
 
145
  } else if (audioFormat == WA_IMA_ADPCM) {
 
146
    mimeType = "DVI4";
 
147
    // Use a static payload type, if one is defined:                                                                               
 
148
    if (numChannels == 1) {
 
149
      if (samplingFrequency == 8000) {
 
150
        payloadFormatCode = 5; // a static RTP payload type                                                                        
 
151
      } else if (samplingFrequency == 16000) {
 
152
        payloadFormatCode = 6; // a static RTP payload type                                                                        
 
153
      } else if (samplingFrequency == 11025) {
 
154
        payloadFormatCode = 16; // a static RTP payload type                                                                       
 
155
      } else if (samplingFrequency == 22050) {
 
156
        payloadFormatCode = 17; // a static RTP payload type                                                                       
 
157
      }
 
158
    }
 
159
  } else { //unknown format                                                                                                        
 
160
    *env << "Unknown audio format code \"" << audioFormat << "\" in WAV file header\n";
 
161
    exit(1);
134
162
  }
135
163
 
136
164
  // Create 'groupsocks' for RTP and RTCP:
137
165
  struct in_addr destinationAddress;
138
166
  destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);
139
167
  // Note: This is a multicast address.  If you wish instead to stream
140
 
  // using unicast, then you should use the "testOnDemandRTSPServer"
141
 
  // test program - not this test program - as a model.
 
168
  // using unicast, then you should use the "testOnDemandRTSPServer" demo application,
 
169
  // or the "LIVE555 Media Server" - not this application - as a model.
142
170
 
143
171
  const unsigned short rtpPortNum = 2222;
144
172
  const unsigned short rtcpPortNum = rtpPortNum+1;
154
182
    = new Groupsock(*env, destinationAddress, rtcpPort, ttl);
155
183
  sessionState.rtcpGroupsock->multicastSendOnly(); // we're a SSM source
156
184
 
157
 
  // Create an appropriate audio RTP sink (using "SimpleRTPSink")
158
 
  // from the RTP 'groupsock':
 
185
  // Create an appropriate audio RTP sink (using "SimpleRTPSink") from the RTP 'groupsock':
159
186
  sessionState.sink
160
187
    = SimpleRTPSink::createNew(*env, sessionState.rtpGroupsock,
161
188
                               payloadFormatCode, samplingFrequency,
162
189
                               "audio", mimeType, numChannels);
163
190
 
164
191
  // Create (and start) a 'RTCP instance' for this RTP sink:
165
 
  const unsigned estimatedSessionBandwidth = bitsPerSecond/1000;
166
 
      // in kbps; for RTCP b/w share
 
192
  const unsigned estimatedSessionBandwidth = (bitsPerSecond + 500)/1000; // in kbps; for RTCP b/w share
167
193
  const unsigned maxCNAMElen = 100;
168
194
  unsigned char CNAME[maxCNAMElen+1];
169
195
  gethostname((char*)CNAME, maxCNAMElen);