- Timestamp:
- Jan 28, 2009 6:03:12 PM (16 years ago)
- Location:
- pjproject/branches/projects/aps-direct
- Files:
-
- 1 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/build.symbian/bld.inf
r2174 r2434 1 #define SND_USE_NULL 02 #define SND_USE_APS 03 4 1 prj_platforms 5 2 winscw … … 26 23 27 24 /* Sound device impl */ 28 #if SND_USE_NULL 29 null_audio.mmp 30 #elif SND_USE_APS 31 symbian_audio_aps.mmp 32 #else 33 symbian_audio.mmp 34 #endif 25 symbian_audio.mmp 35 26 36 27 /* Applications */ -
pjproject/branches/projects/aps-direct/build.symbian/pjmedia.mmp
r2262 r2434 41 41 SOURCE codec.c 42 42 SOURCE conference.c 43 SOURCE conf_switch.c 43 44 SOURCE echo_common.c 44 45 SOURCE echo_port.c -
pjproject/branches/projects/aps-direct/build.symbian/symbian_audio.mmp
r1965 r2434 25 25 26 26 OPTION CW -lang c++ 27 28 //29 // GCCE optimization setting30 //31 27 OPTION GCCE -O2 -fno-unit-at-a-time 32 28 … … 34 30 MACRO PJ_SYMBIAN=1 35 31 32 SOURCE nullsound.c 36 33 SOURCE symbian_sound.cpp 34 SOURCE symbian_sound_aps.cpp 37 35 38 36 SYSTEMINCLUDE ..\pjlib\include … … 41 39 SYSTEMINCLUDE \epoc32\include 42 40 SYSTEMINCLUDE \epoc32\include\libc 41 SYSTEMINCLUDE \epoc32\include\mmf\server 42 SYSTEMINCLUDE \epoc32\include\mmf\common 43 SYSTEMINCLUDE \epoc32\include\mda\common 43 44 44 45 SYSTEMINCLUDE \epoc32\include\mmf\plugin -
pjproject/branches/projects/aps-direct/build.symbian/symbian_ua.mmp
r2384 r2434 1 #define SND_USE_ NULL 02 #define SND_USE_ APS 01 #define SND_USE_APS 1 2 #define SND_USE_VAS 0 3 3 4 TARGET symbian_ua.exe5 TARGETTYPE exe6 UID 0x0 0xA000000D4 TARGET symbian_ua.exe 5 TARGETTYPE exe 6 UID 0x0 0xA000000D 7 7 8 SOURCEPATH ..\pjsip-apps\src\symbian_ua8 SOURCEPATH ..\pjsip-apps\src\symbian_ua 9 9 10 MACRO PJ_M_I386=111 MACRO PJ_SYMBIAN=110 MACRO PJ_M_I386=1 11 MACRO PJ_SYMBIAN=1 12 12 13 13 // Source files 14 14 15 SOURCE ua.cpp16 SOURCE main_symbian.cpp15 SOURCE ua.cpp 16 SOURCE main_symbian.cpp 17 17 18 DOCUMENT ua.h18 DOCUMENT ua.h 19 19 20 START RESOURCE symbian_ua_reg.rss20 START RESOURCE symbian_ua_reg.rss 21 21 TARGETPATH \private\10003a3f\apps 22 22 END 23 23 24 SYSTEMINCLUDE ..\pjlib\include25 SYSTEMINCLUDE ..\pjlib-util\include26 SYSTEMINCLUDE ..\pjnath\include27 SYSTEMINCLUDE ..\pjmedia\include28 SYSTEMINCLUDE ..\pjsip\include24 SYSTEMINCLUDE ..\pjlib\include 25 SYSTEMINCLUDE ..\pjlib-util\include 26 SYSTEMINCLUDE ..\pjnath\include 27 SYSTEMINCLUDE ..\pjmedia\include 28 SYSTEMINCLUDE ..\pjsip\include 29 29 30 SYSTEMINCLUDE \epoc32\include31 SYSTEMINCLUDE \epoc32\include\libc30 SYSTEMINCLUDE \epoc32\include 31 SYSTEMINCLUDE \epoc32\include\libc 32 32 33 STATICLIBRARY pjsua_lib.lib pjsip_ua.lib 34 STATICLIBRARY pjsip_simple.lib pjsip.lib pjsdp.lib pjmedia.lib 35 STATICLIBRARY pjnath.lib pjlib_util.lib pjlib.lib 36 STATICLIBRARY libsrtp.lib 37 STATICLIBRARY libgsmcodec.lib libspeexcodec.lib 33 STATICLIBRARY pjsua_lib.lib pjsip_ua.lib 34 STATICLIBRARY pjsip_simple.lib pjsip.lib pjsdp.lib pjmedia.lib 35 STATICLIBRARY pjnath.lib pjlib_util.lib pjlib.lib 36 STATICLIBRARY libsrtp.lib 37 STATICLIBRARY libgsmcodec.lib libspeexcodec.lib 38 STATICLIBRARY symbian_audio.lib 38 39 39 #if SND_USE_NULL 40 STATICLIBRARY null_audio.lib 41 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment 42 #elif SND_USE_APS 43 STATICLIBRARY symbian_audio_aps.lib 44 LIBRARY APSSession2.lib 45 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD 46 MACRO PJMEDIA_SYM_SND_USE_APS=1 40 #if SND_USE_APS 41 LIBRARY APSSession2.lib 42 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD 43 #elif SND_USE_VAS 44 // LIBRARY 45 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD 47 46 #else 48 STATICLIBRARY symbian_audio.lib 49 LIBRARY mediaclientaudiostream.lib 50 LIBRARY mediaclientaudioinputstream.lib 51 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment 47 LIBRARY mediaclientaudiostream.lib 48 LIBRARY mediaclientaudioinputstream.lib 49 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment 52 50 #endif 53 51 … … 56 54 #endif 57 55 58 LIBRARY esock.lib insock.lib charconv.lib euser.lib estlib.lib commdb.lib apengine.lib56 LIBRARY esock.lib insock.lib charconv.lib euser.lib estlib.lib commdb.lib apengine.lib 59 57 60 58 // The default 8KB seems to be insufficient with all bells and -
pjproject/branches/projects/aps-direct/build.symbian/symsndtest.mmp
r2257 r2434 1 #define SND_USE_ NULL 02 #define SND_USE_ APS 01 #define SND_USE_APS 1 2 #define SND_USE_VAS 0 3 3 4 TARGET symsndtest.exe5 TARGETTYPE exe6 UID 0x0 0xA000000E4 TARGET symsndtest.exe 5 TARGETTYPE exe 6 UID 0x0 0xA000000E 7 7 8 SOURCEPATH ..\pjsip-apps\src\symsndtest8 SOURCEPATH ..\pjsip-apps\src\symsndtest 9 9 10 MACRO PJ_M_I386=111 MACRO PJ_SYMBIAN=110 MACRO PJ_M_I386=1 11 MACRO PJ_SYMBIAN=1 12 12 13 13 // Test files 14 14 15 SOURCE app_main.cpp16 SOURCE main_symbian.cpp15 SOURCE app_main.cpp 16 SOURCE main_symbian.cpp 17 17 18 START RESOURCE symsndtest_reg.rss18 START RESOURCE symsndtest_reg.rss 19 19 TARGETPATH \private\10003a3f\apps 20 20 END 21 21 22 SYSTEMINCLUDE ..\pjlib\include23 SYSTEMINCLUDE ..\pjmedia\include22 SYSTEMINCLUDE ..\pjlib\include 23 SYSTEMINCLUDE ..\pjmedia\include 24 24 25 SYSTEMINCLUDE \epoc32\include26 SYSTEMINCLUDE \epoc32\include\libc25 SYSTEMINCLUDE \epoc32\include 26 SYSTEMINCLUDE \epoc32\include\libc 27 27 28 LIBRARY charconv.lib euser.lib estlib.lib 29 LIBRARY esock.lib insock.lib 30 STATICLIBRARY pjlib.lib pjmedia.lib 28 LIBRARY charconv.lib euser.lib estlib.lib 29 LIBRARY esock.lib insock.lib 30 STATICLIBRARY pjlib.lib pjmedia.lib 31 STATICLIBRARY symbian_audio.lib 31 32 32 #if SND_USE_NULL 33 STATICLIBRARY null_audio.lib 34 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment 35 #elif SND_USE_APS 36 SOURCEPATH ..\pjmedia\src\pjmedia 37 SOURCE symbian_sound_aps.cpp 38 39 SYSTEMINCLUDE \epoc32\include\mmf\server 40 SYSTEMINCLUDE \epoc32\include\mmf\common 41 SYSTEMINCLUDE \epoc32\include\mda\common 42 43 //STATICLIBRARY symbian_audio_aps.lib 44 LIBRARY APSSession2.lib 45 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD 33 #if SND_USE_APS 34 LIBRARY APSSession2.lib 35 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD 36 #elif SND_USE_VAS 37 // LIBRARY 38 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment MultimediaDD 46 39 #else 47 STATICLIBRARY symbian_audio.lib 48 LIBRARY mediaclientaudiostream.lib 49 LIBRARY mediaclientaudioinputstream.lib 50 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment 40 LIBRARY mediaclientaudiostream.lib 41 LIBRARY mediaclientaudioinputstream.lib 42 CAPABILITY NetworkServices LocalServices ReadUserData WriteUserData UserEnvironment 51 43 #endif 52 44 -
pjproject/branches/projects/aps-direct/pjmedia/build/pjmedia.vcproj
r2430 r2434 96 96 </Configuration> 97 97 <Configuration 98 Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"99 OutputDirectory="output\$(ProjectName)-$(PlatformName)-$(ConfigurationName)"100 IntermediateDirectory="$(OutDir)"101 ConfigurationType="4"102 CharacterSet="1"103 >104 <Tool105 Name="VCPreBuildEventTool"106 />107 <Tool108 Name="VCCustomBuildTool"109 />110 <Tool111 Name="VCXMLDataGeneratorTool"112 />113 <Tool114 Name="VCWebServiceProxyGeneratorTool"115 />116 <Tool117 Name="VCMIDLTool"118 />119 <Tool120 Name="VCCLCompilerTool"121 ExecutionBucket="7"122 Optimization="2"123 FavorSizeOrSpeed="2"124 AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."125 PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;$(ARCHFAM);$(_ARCHFAM_);SMARTPHONE2003_UI_MODEL;SMARTPHONE2003_UI_MODEL"126 ExceptionHandling="0"127 RuntimeLibrary="0"128 WarningLevel="3"129 DebugInformationFormat="0"130 CompileAs="0"131 />132 <Tool133 Name="VCManagedResourceCompilerTool"134 />135 <Tool136 Name="VCResourceCompilerTool"137 />138 <Tool139 Name="VCPreLinkEventTool"140 />141 <Tool142 Name="VCLibrarianTool"143 AdditionalOptions=""144 />145 <Tool146 Name="VCALinkTool"147 />148 <Tool149 Name="VCXDCMakeTool"150 />151 <Tool152 Name="VCBscMakeTool"153 />154 <Tool155 Name="VCCodeSignTool"156 />157 <Tool158 Name="VCPostBuildEventTool"159 />160 <DeploymentTool161 ForceDirty="-1"162 RemoteDirectory=""163 RegisterOutput="0"164 AdditionalFiles=""165 />166 <DebuggerTool167 />168 </Configuration>169 <Configuration170 98 Name="Debug|Win32" 171 99 OutputDirectory=".\output\pjmedia-i386-win32-vc8-debug" … … 244 172 </Configuration> 245 173 <Configuration 174 Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)" 175 OutputDirectory="output\$(ProjectName)-$(PlatformName)-$(ConfigurationName)" 176 IntermediateDirectory="$(OutDir)" 177 ConfigurationType="4" 178 CharacterSet="1" 179 > 180 <Tool 181 Name="VCPreBuildEventTool" 182 /> 183 <Tool 184 Name="VCCustomBuildTool" 185 /> 186 <Tool 187 Name="VCXMLDataGeneratorTool" 188 /> 189 <Tool 190 Name="VCWebServiceProxyGeneratorTool" 191 /> 192 <Tool 193 Name="VCMIDLTool" 194 /> 195 <Tool 196 Name="VCCLCompilerTool" 197 ExecutionBucket="7" 198 Optimization="2" 199 FavorSizeOrSpeed="2" 200 AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.." 201 PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;$(ARCHFAM);$(_ARCHFAM_);SMARTPHONE2003_UI_MODEL;SMARTPHONE2003_UI_MODEL" 202 ExceptionHandling="0" 203 RuntimeLibrary="0" 204 WarningLevel="3" 205 DebugInformationFormat="0" 206 CompileAs="0" 207 /> 208 <Tool 209 Name="VCManagedResourceCompilerTool" 210 /> 211 <Tool 212 Name="VCResourceCompilerTool" 213 /> 214 <Tool 215 Name="VCPreLinkEventTool" 216 /> 217 <Tool 218 Name="VCLibrarianTool" 219 AdditionalOptions="" 220 /> 221 <Tool 222 Name="VCALinkTool" 223 /> 224 <Tool 225 Name="VCXDCMakeTool" 226 /> 227 <Tool 228 Name="VCBscMakeTool" 229 /> 230 <Tool 231 Name="VCCodeSignTool" 232 /> 233 <Tool 234 Name="VCPostBuildEventTool" 235 /> 236 <DeploymentTool 237 ForceDirty="-1" 238 RemoteDirectory="" 239 RegisterOutput="0" 240 AdditionalFiles="" 241 /> 242 <DebuggerTool 243 /> 244 </Configuration> 245 <Configuration 246 246 Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)" 247 247 OutputDirectory="output\$(ProjectName)-$(PlatformName)-$(ConfigurationName)" … … 435 435 </File> 436 436 <File 437 RelativePath="..\src\pjmedia\conf_switch.c" 438 > 439 </File> 440 <File 437 441 RelativePath="..\src\pjmedia\conference.c" 438 442 > -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia-codec/config.h
r2394 r2434 195 195 #endif 196 196 197 /** 198 * Enable Passthrough codecs. 199 * 200 * Default: 0 201 */ 202 #ifndef PJMEDIA_HAS_PASSTHROUGH_CODECS 203 # define PJMEDIA_HAS_PASSTHROUGH_CODECS 0 204 #endif 197 205 198 206 #endif /* __PJMEDIA_CODEC_CONFIG_H__ */ -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/conference.h
r2394 r2434 57 57 unsigned slot; /**< Slot number. */ 58 58 pj_str_t name; /**< Port name. */ 59 pjmedia_fourcc format; /**< Format (FourCC identifier) */ 59 60 pjmedia_port_op tx_setting; /**< Transmit settings. */ 60 61 pjmedia_port_op rx_setting; /**< Receive settings. */ -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/config.h
r2394 r2434 45 45 #endif 46 46 47 /** 48 * Specify whether we prefer to use audio switch board rather than 49 * conference bridge. 50 * 51 * Audio switch board is a kind of simplified version of conference 52 * bridge, but not really the subset of conference bridge. It has 53 * stricter rules on audio routing among the pjmedia ports and has 54 * no audio mixing capability. The power of it is it could work with 55 * encoded audio frames where conference brigde couldn't. 56 * 57 * Default: 0 58 */ 59 #ifndef PJMEDIA_CONF_USE_SWITCH_BOARD 60 # define PJMEDIA_CONF_USE_SWITCH_BOARD 0 61 #endif 62 47 63 /* 48 64 * Types of sound stream backends. … … 60 76 /** Constant for Win32 MME sound backend. */ 61 77 #define PJMEDIA_SOUND_WIN32_MME_SOUND 3 78 79 /** Constant for Symbian Multimedia Audio Stream backend. */ 80 #define PJMEDIA_SOUND_SYMB_MDA_SOUND 4 81 82 /** Constant for Symbian APS backend. */ 83 #define PJMEDIA_SOUND_SYMB_APS_SOUND 5 84 85 /** Constant for Symbian VAS backend. */ 86 #define PJMEDIA_SOUND_SYMB_VAS_SOUND 6 87 62 88 63 89 /** When this is set, pjmedia will not provide any sound device backend. -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/port.h
r2394 r2434 26 26 */ 27 27 #include <pjmedia/types.h> 28 #include <pj/assert.h> 28 29 #include <pj/os.h> 29 30 … … 212 213 pj_bool_t need_info; /**< Need info on connect? */ 213 214 unsigned pt; /**< Payload type (can be dynamic). */ 215 pjmedia_fourcc format; /**< Format (FourCC identifier) */ 214 216 pj_str_t encoding_name; /**< Encoding name. */ 215 217 unsigned clock_rate; /**< Sampling rate. */ … … 227 229 { 228 230 PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */ 229 PJMEDIA_FRAME_TYPE_AUDIO /**< Normal audio frame. */ 231 PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */ 232 PJMEDIA_FRAME_TYPE_EXTENDED /**< Extended audio frame. */ 230 233 231 234 } pjmedia_frame_type; … … 250 253 251 254 /** 255 * The pjmedia_frame_ext is used to carry a more complex audio frames than 256 * the typical PCM audio frames, and it is signaled by setting the "type" 257 * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set, 258 * application may typecast pjmedia_frame to pjmedia_frame_ext. 259 * 260 * This structure may contain more than one audio frames, which subsequently 261 * will be called subframes in this structure. The subframes section 262 * immediately follows the end of this structure, and each subframe is 263 * represented by pjmedia_frame_ext_subframe structure. Every next 264 * subframe immediately follows the previous subframe, and all subframes 265 * are byte-aligned although its payload may not be byte-aligned. 266 */ 267 typedef struct pjmedia_frame_ext { 268 pjmedia_frame base; /**< Base frame info */ 269 pj_uint16_t samples_cnt; /**< Number of samples in this frame */ 270 pj_uint16_t subframe_cnt; /**< Number of (sub)frames in this frame */ 271 272 /* Zero or more (sub)frames follows immediately after this, 273 * each will be represented by pjmedia_frame_ext_subframe 274 */ 275 } pjmedia_frame_ext; 276 277 /** 278 * This structure represents the individual subframes in the 279 * pjmedia_frame_ext structure. 280 */ 281 typedef struct pjmedia_frame_ext_subframe { 282 pj_uint16_t bitlen; /**< Number of bits in the data */ 283 pj_uint8_t data[1]; /**< Start of encoded data */ 284 } pjmedia_frame_ext_subframe; 285 286 287 /* Append one subframe to the frame_ext */ 288 PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm, 289 const void *src, 290 pj_uint16_t bitlen, 291 pj_uint16_t samples_cnt) 292 { 293 pj_uint8_t *p; 294 unsigned i, tmp; 295 296 p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext); 297 for (i = 0; i < frm->subframe_cnt; ++i) { 298 pjmedia_frame_ext_subframe *fsub; 299 fsub = (pjmedia_frame_ext_subframe*) p; 300 p += fsub->bitlen / 8; 301 if (fsub->bitlen % 8) 302 ++p; 303 } 304 305 tmp = bitlen / 8; 306 if (bitlen % 8) ++tmp; 307 pj_memcpy(p, &bitlen, sizeof(bitlen)); 308 pj_memcpy(p + sizeof(bitlen), src, tmp); 309 frm->subframe_cnt++; 310 frm->samples_cnt = frm->samples_cnt + samples_cnt; 311 } 312 313 /* Get the pointer and length of the n-th subframe */ 314 PJ_INLINE(pjmedia_frame_ext_subframe*) 315 pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, 316 unsigned n) 317 { 318 pj_uint8_t *p; 319 unsigned i; 320 pjmedia_frame_ext_subframe *tmp; 321 322 pj_assert(n < frm->subframe_cnt); 323 324 p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext); 325 for (i = 0; i < n; ++i) { 326 tmp = (pjmedia_frame_ext_subframe*) p; 327 p += tmp->bitlen / 8; 328 if (tmp->bitlen % 8) 329 ++p; 330 } 331 332 tmp = (pjmedia_frame_ext_subframe*) p; 333 return tmp; 334 } 335 336 /** 252 337 * Port interface. 253 338 */ -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/symbian_sound_aps.h
r2394 r2434 32 32 33 33 /** 34 * Declaration of APS sound setting. 35 */ 36 typedef struct pjmedia_snd_aps_setting 37 { 38 pjmedia_fourcc format; /**< Format (FourCC ID). */ 39 pj_uint32_t bitrate; /**< Bitrate (bps). */ 40 pj_uint32_t mode; /**< Mode, currently only used 41 for specifying iLBC mode, 42 20ms or 30ms frame size. */ 43 pj_bool_t plc; /**< PLC enabled/disabled. */ 44 pj_bool_t vad; /**< VAD enabled/disabled. */ 45 pj_bool_t cng; /**< CNG enabled/disabled. */ 46 pj_bool_t loudspk; /**< Audio routed to loudspeaker.*/ 47 48 } pjmedia_snd_aps_setting; 49 50 51 /** 34 52 * Activate/deactivate loudspeaker, when loudspeaker is inactive, audio 35 53 * will be routed to earpiece. … … 48 66 49 67 68 /** 69 * Set a codec and its settings to be used on the next sound device session. 70 * 71 * @param setting APS sound device setting, see @pjmedia_snd_aps_setting. 72 * 73 * @return PJ_SUCCESS on success. 74 */ 75 PJ_DECL(pj_status_t) pjmedia_snd_aps_modify_setting( 76 const pjmedia_snd_aps_setting *setting); 77 78 50 79 PJ_END_DECL 51 80 -
pjproject/branches/projects/aps-direct/pjmedia/include/pjmedia/types.h
r2394 r2434 48 48 */ 49 49 50 /** 51 * Top most media type. 50 /** 51 * Top most media type. 52 52 */ 53 53 typedef enum pjmedia_type … … 62 62 PJMEDIA_TYPE_VIDEO = 2, 63 63 64 /** Unknown media type, in this case the name will be specified in 64 /** Unknown media type, in this case the name will be specified in 65 65 * encoding_name. 66 66 */ … … 73 73 74 74 75 /** 76 * Media transport protocol. 75 /** 76 * Media transport protocol. 77 77 */ 78 78 typedef enum pjmedia_tp_proto … … 93 93 94 94 95 /** 96 * Media direction. 95 /** 96 * Media direction. 97 97 */ 98 98 typedef enum pjmedia_dir … … 139 139 140 140 141 /** 142 * Opa gue declaration of media endpoint.141 /** 142 * Opaque declaration of media endpoint. 143 143 */ 144 144 typedef struct pjmedia_endpt pjmedia_endpt; … … 151 151 152 152 153 /** 153 /** 154 154 * Media socket info is used to describe the underlying sockets 155 155 * to be used as media transport. … … 179 179 } pjmedia_sock_info; 180 180 181 /** 182 * Declaration of FourCC type. 183 */ 184 typedef union pjmedia_fourcc { 185 pj_uint32_t u32; 186 char c[4]; 187 } pjmedia_fourcc; 188 189 190 /** 191 * FourCC packing macro. 192 */ 193 #define PJMEDIA_FOURCC_PACK(C1, C2, C3, C4) ( C1<<24 | C2<<16 | C3<<8 | C4 ) 194 195 /** 196 * FourCC identifier definitions. 197 */ 198 #define PJMEDIA_FOURCC_L16 PJMEDIA_FOURCC_PACK(' ', 'L', '1', '6') 199 #define PJMEDIA_FOURCC_G711A PJMEDIA_FOURCC_PACK('G', '7', '1', '1') 200 #define PJMEDIA_FOURCC_G711U PJMEDIA_FOURCC_PACK('U', 'L', 'A', 'W') 201 #define PJMEDIA_FOURCC_AMR PJMEDIA_FOURCC_PACK(' ', 'A', 'M', 'R') 202 #define PJMEDIA_FOURCC_G729 PJMEDIA_FOURCC_PACK('G', '7', '2', '9') 203 #define PJMEDIA_FOURCC_ILBC PJMEDIA_FOURCC_PACK('i', 'L', 'B', 'C') 204 181 205 182 206 /** 183 207 * This is a general purpose function set PCM samples to zero. 184 * Since this function is needed by many parts of the library, 208 * Since this function is needed by many parts of the library, 185 209 * by putting this functionality in one place, it enables some. 186 210 * clever people to optimize this function. … … 206 230 /** 207 231 * This is a general purpose function to copy samples from/to buffers with 208 * equal size. Since this function is needed by many parts of the library, 232 * equal size. Since this function is needed by many parts of the library, 209 233 * by putting this functionality in one place, it enables some. 210 234 * clever people to optimize this function. … … 221 245 unsigned i; 222 246 count >>= 1; 223 for (i=0; i<count; ++i) 247 for (i=0; i<count; ++i) 224 248 ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i]; 225 249 #endif … … 229 253 /** 230 254 * This is a general purpose function to copy samples from/to buffers with 231 * equal size. Since this function is needed by many parts of the library, 255 * equal size. Since this function is needed by many parts of the library, 232 256 * by putting this functionality in one place, it enables some. 233 257 * clever people to optimize this function. … … 244 268 unsigned i; 245 269 count >>= 1; 246 for (i=0; i<count; ++i) 270 for (i=0; i<count; ++i) 247 271 ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i]; 248 272 #endif -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/conference.c
r2394 r2434 34 34 #include <pj/string.h> 35 35 36 #if !defined(PJMEDIA_CONF_USE_SWITCH_BOARD) || PJMEDIA_CONF_USE_SWITCH_BOARD==0 36 37 37 38 /* CONF_DEBUG enables detailed operation of the conference bridge. … … 1988 1989 } 1989 1990 1991 #endif -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound.cpp
r2394 r2434 24 24 #include <pj/os.h> 25 25 26 #if PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_SYMB_MDA_SOUND 26 27 27 28 /* … … 943 944 return PJ_SUCCESS; 944 945 } 946 947 #endif -
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound_aps.cpp
r2418 r2434 18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 #include <pjmedia/symbian_sound_aps.h> 20 21 #include <pjmedia/sound.h> 21 22 #include <pjmedia/alaw_ulaw.h> … … 26 27 #include <pj/os.h> 27 28 29 #if PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_SYMB_APS_SOUND 30 28 31 #include <e32msgqueue.h> 29 32 #include <sounddevice.h> … … 46 49 #endif 47 50 48 static pjmedia_snd_dev_info symbian_snd_dev_info = 51 static pjmedia_snd_dev_info symbian_snd_dev_info = 49 52 { 50 53 "Symbian Sound Device (APS)", … … 57 60 extern TPtrC APP_UID; 58 61 59 /* Default setting for loudspeaker */ 60 static pj_bool_t act_loudspeaker = PJ_FALSE; 62 /* Default setting */ 63 static pjmedia_snd_aps_setting def_setting; 64 65 /* APS G.711 frame length */ 66 static pj_uint8_t aps_g711_frame_len; 67 68 /* Pool factory */ 69 static pj_pool_factory *snd_pool_factory; 61 70 62 71 /* Forward declaration of CPjAudioEngine */ 63 72 class CPjAudioEngine; 64 73 65 /* 66 * PJMEDIA Sound Stream instance 74 /* 75 * PJMEDIA Sound Stream instance 67 76 */ 68 77 struct pjmedia_snd_stream 69 78 { 70 79 // Pool 71 pj_pool_t 80 pj_pool_t *pool; 72 81 73 82 // Common settings. 74 pjmedia_dir dir; 75 unsigned clock_rate; 76 unsigned channel_count; 77 unsigned samples_per_frame; 83 pjmedia_dir dir; 84 unsigned clock_rate; 85 unsigned channel_count; 86 unsigned samples_per_frame; 87 pjmedia_snd_rec_cb rec_cb; 88 pjmedia_snd_play_cb play_cb; 89 void *user_data; 78 90 79 91 // Audio engine 80 CPjAudioEngine *engine; 92 CPjAudioEngine *engine; 93 94 pj_timestamp ts_play; 95 pj_timestamp ts_rec; 96 97 pj_int16_t *play_buf; 98 pj_uint16_t play_buf_len; 99 pj_uint16_t play_buf_start; 100 pj_int16_t *rec_buf; 101 pj_uint16_t rec_buf_len; 81 102 }; 82 83 static pj_pool_factory *snd_pool_factory;84 103 85 104 … … 87 106 * Utility: print sound device error 88 107 */ 89 static void snd_perror(const char *title, TInt rc) 108 static void snd_perror(const char *title, TInt rc) 90 109 { 91 110 PJ_LOG(1,(THIS_FILE, "%s (error code=%d)", title, rc)); 92 111 } 93 112 94 113 ////////////////////////////////////////////////////////////////////////////// 95 114 // 96 115 116 typedef void(*PjAudioCallback)(TAPSCommBuffer &buf, void *user_data); 117 97 118 /** 98 119 * Abstract class for handler of callbacks from APS client. … … 101 122 { 102 123 public: 124 MQueueHandlerObserver(PjAudioCallback RecCb_, PjAudioCallback PlayCb_, 125 void *UserData_) 126 : RecCb(RecCb_), PlayCb(PlayCb_), UserData(UserData_) 127 {} 128 103 129 virtual void InputStreamInitialized(const TInt aStatus) = 0; 104 130 virtual void OutputStreamInitialized(const TInt aStatus) = 0; 105 131 virtual void NotifyError(const TInt aError) = 0; 106 132 107 virtual void RecCb(TAPSCommBuffer &buffer) = 0; 108 virtual void PlayCb(TAPSCommBuffer &buffer) = 0; 133 public: 134 PjAudioCallback RecCb; 135 PjAudioCallback PlayCb; 136 void *UserData; 109 137 }; 110 138 … … 133 161 }; 134 162 135 static CQueueHandler* NewL(MQueueHandlerObserver* aObserver, 136 RMsgQueue<TAPSCommBuffer>* aQ, 163 static CQueueHandler* NewL(MQueueHandlerObserver* aObserver, 164 RMsgQueue<TAPSCommBuffer>* aQ, 165 RMsgQueue<TAPSCommBuffer>* aWriteQ, 137 166 TQueueHandlerType aType) 138 167 { 139 CQueueHandler* self = new (ELeave) CQueueHandler(aObserver, aQ, aType); 168 CQueueHandler* self = new (ELeave) CQueueHandler(aObserver, aQ, aWriteQ, 169 aType); 140 170 CleanupStack::PushL(self); 141 171 self->ConstructL(); … … 155 185 private: 156 186 // Constructor 157 CQueueHandler(MQueueHandlerObserver* aObserver, 158 RMsgQueue<TAPSCommBuffer>* aQ, 159 TQueueHandlerType aType) 187 CQueueHandler(MQueueHandlerObserver* aObserver, 188 RMsgQueue<TAPSCommBuffer>* aQ, 189 RMsgQueue<TAPSCommBuffer>* aWriteQ, 190 TQueueHandlerType aType) 160 191 : CActive(CActive::EPriorityHigh), 161 iQ(aQ), i Observer(aObserver), iType(aType)192 iQ(aQ), iWriteQ(aWriteQ), iObserver(aObserver), iType(aType) 162 193 { 163 194 CActiveScheduler::Add(this); … … 178 209 iObserver->NotifyError(iStatus.Int()); 179 210 return; 180 } 211 } 181 212 182 213 TAPSCommBuffer buffer; … … 191 222 case ERecordQueue: 192 223 if (buffer.iCommand == EAPSRecordData) { 193 iObserver->RecCb(buffer); 224 iObserver->RecCb(buffer, iObserver->UserData); 225 } else { 226 iObserver->NotifyError(buffer.iStatus); 194 227 } 195 228 break; … … 200 233 case EAPSPlayData: 201 234 if (buffer.iStatus == KErrUnderflow) { 202 iObserver->PlayCb(buffer); 235 iObserver->PlayCb(buffer, iObserver->UserData); 236 iWriteQ->Send(buffer); 203 237 } 204 238 break; … … 225 259 // sent from the APS main thread through EPlayCommQueue 226 260 case EAPSRecorderInitialize: 227 if (buffer.iStatus == KErrNone) {228 iObserver->InputStreamInitialized(buffer.iStatus);229 break;230 }231 261 case EAPSRecordData: 262 default: 232 263 iObserver->NotifyError(buffer.iStatus); 233 break;234 default:235 264 break; 236 265 } … … 246 275 } 247 276 277 TInt RunError(TInt) { 278 return 0; 279 } 280 248 281 // Data 249 282 RMsgQueue<TAPSCommBuffer> *iQ; // (not owned) 283 RMsgQueue<TAPSCommBuffer> *iWriteQ; // (not owned) 250 284 MQueueHandlerObserver *iObserver; // (not owned) 251 285 TQueueHandlerType iType; 252 286 }; 253 287 288 /* 289 * Audio setting for CPjAudioEngine. 290 */ 291 class CPjAudioSetting 292 { 293 public: 294 TFourCC fourcc; 295 TAPSCodecMode mode; 296 TBool plc; 297 TBool vad; 298 TBool cng; 299 TBool loudspk; 300 }; 254 301 255 302 /* … … 269 316 270 317 static CPjAudioEngine *NewL(pjmedia_snd_stream *parent_strm, 271 pjmedia_snd_rec_cb rec_cb, 272 pjmedia_snd_play_cb play_cb, 273 void *user_data); 318 PjAudioCallback rec_cb, 319 PjAudioCallback play_cb, 320 void *user_data, 321 const CPjAudioSetting &setting); 274 322 275 323 TInt StartL(); … … 280 328 private: 281 329 CPjAudioEngine(pjmedia_snd_stream *parent_strm, 282 pjmedia_snd_rec_cb rec_cb, 283 pjmedia_snd_play_cb play_cb, 284 void *user_data); 330 PjAudioCallback rec_cb, 331 PjAudioCallback play_cb, 332 void *user_data, 333 const CPjAudioSetting &setting); 285 334 void ConstructL(); 286 335 287 336 TInt InitPlayL(); 288 337 TInt InitRecL(); 289 338 TInt StartStreamL(); 290 339 291 340 // Inherited from MQueueHandlerObserver 292 341 virtual void InputStreamInitialized(const TInt aStatus); … … 294 343 virtual void NotifyError(const TInt aError); 295 344 296 virtual void RecCb(TAPSCommBuffer &buffer);297 virtual void PlayCb(TAPSCommBuffer &buffer);298 299 345 State state_; 300 346 pjmedia_snd_stream *parentStrm_; 301 pjmedia_snd_rec_cb recCb_; 302 pjmedia_snd_play_cb playCb_; 303 void *userData_; 304 pj_uint32_t TsPlay_; 305 pj_uint32_t TsRec_; 347 CPjAudioSetting setting_; 306 348 307 349 RAPSSession iSession; 308 TAPSInitSettings iSettings; 350 TAPSInitSettings iPlaySettings; 351 TAPSInitSettings iRecSettings; 352 309 353 RMsgQueue<TAPSCommBuffer> iReadQ; 310 354 RMsgQueue<TAPSCommBuffer> iReadCommQ; … … 315 359 CQueueHandler *iRecCommHandler; 316 360 CQueueHandler *iRecHandler; 317 318 static pj_uint8_t aps_samples_per_frame;319 320 pj_int16_t *play_buf;321 pj_uint16_t play_buf_len;322 pj_uint16_t play_buf_start;323 pj_int16_t *rec_buf;324 pj_uint16_t rec_buf_len;325 361 }; 326 362 327 363 328 pj_uint8_t CPjAudioEngine::aps_samples_per_frame = 0;329 330 331 364 CPjAudioEngine* CPjAudioEngine::NewL(pjmedia_snd_stream *parent_strm, 332 pjmedia_snd_rec_cb rec_cb, 333 pjmedia_snd_play_cb play_cb, 334 void *user_data) 365 PjAudioCallback rec_cb, 366 PjAudioCallback play_cb, 367 void *user_data, 368 const CPjAudioSetting &setting) 335 369 { 336 370 CPjAudioEngine* self = new (ELeave) CPjAudioEngine(parent_strm, 337 371 rec_cb, play_cb, 338 user_data); 372 user_data, 373 setting); 339 374 CleanupStack::PushL(self); 340 375 self->ConstructL(); … … 344 379 345 380 CPjAudioEngine::CPjAudioEngine(pjmedia_snd_stream *parent_strm, 346 pjmedia_snd_rec_cb rec_cb, 347 pjmedia_snd_play_cb play_cb, 348 void *user_data) 349 : state_(STATE_NULL), 381 PjAudioCallback rec_cb, 382 PjAudioCallback play_cb, 383 void *user_data, 384 const CPjAudioSetting &setting) 385 : MQueueHandlerObserver(rec_cb, play_cb, user_data), 386 state_(STATE_NULL), 350 387 parentStrm_(parent_strm), 351 recCb_(rec_cb), 352 playCb_(play_cb), 353 userData_(user_data), 388 setting_(setting), 354 389 iPlayCommHandler(0), 355 390 iRecCommHandler(0), … … 362 397 Stop(); 363 398 399 delete iRecHandler; 364 400 delete iPlayCommHandler; 365 iPlayCommHandler = NULL;366 401 delete iRecCommHandler; 367 iRecCommHandler = NULL; 402 403 // On some devices, immediate closing after stopping may cause APS server 404 // panic KERN-EXEC 0, so let's wait for sometime before really closing 405 // the client session. 406 TTime start, now; 407 enum { APS_CLOSE_WAIT_TIME = 200 }; 408 start.UniversalTime(); 409 now.UniversalTime(); 410 while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000) { 411 pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME); 412 now.UniversalTime(); 413 } 368 414 369 415 iSession.Close(); … … 384 430 return 0; 385 431 386 TInt err = iSession.InitializePlayer(i Settings);432 TInt err = iSession.InitializePlayer(iPlaySettings); 387 433 if (err != KErrNone) { 388 434 snd_perror("Failed to initialize player", err); … … 391 437 392 438 // Open message queues for the output stream 393 TBuf<128> buf2 = i Settings.iGlobal;439 TBuf<128> buf2 = iPlaySettings.iGlobal; 394 440 buf2.Append(_L("PlayQueue")); 395 TBuf<128> buf3 = i Settings.iGlobal;441 TBuf<128> buf3 = iPlaySettings.iGlobal; 396 442 buf3.Append(_L("PlayCommQueue")); 397 443 … … 402 448 403 449 // Construct message queue handler 404 iPlayCommHandler = CQueueHandler::NewL(this, 405 &iWriteCommQ, 450 iPlayCommHandler = CQueueHandler::NewL(this, &iWriteCommQ, &iWriteQ, 406 451 CQueueHandler::EPlayCommQueue); 407 452 … … 418 463 419 464 // Initialize input stream device 420 TInt err = iSession.InitializeRecorder(i Settings);421 if (err != KErrNone ) {465 TInt err = iSession.InitializeRecorder(iRecSettings); 466 if (err != KErrNone && err != KErrAlreadyExists) { 422 467 snd_perror("Failed to initialize recorder", err); 423 468 return err; 424 469 } 425 470 426 TBuf<128> buf1 = i Settings.iGlobal;471 TBuf<128> buf1 = iRecSettings.iGlobal; 427 472 buf1.Append(_L("RecordQueue")); 428 TBuf<128> buf4 = i Settings.iGlobal;473 TBuf<128> buf4 = iRecSettings.iGlobal; 429 474 buf4.Append(_L("RecordCommQueue")); 430 475 … … 437 482 438 483 // Construct message queue handlers 439 iRecCommHandler = CQueueHandler::NewL(this, 440 &iReadCommQ, 484 iRecHandler = CQueueHandler::NewL(this, &iReadQ, NULL, 485 CQueueHandler::ERecordQueue); 486 iRecCommHandler = CQueueHandler::NewL(this, &iReadCommQ, NULL, 441 487 CQueueHandler::ERecordCommQueue); 442 488 443 489 // Start observing APS callbacks from on input stream message queue 490 iRecHandler->Start(); 444 491 iRecCommHandler->Start(); 445 492 446 493 return 0; 447 494 } … … 449 496 TInt CPjAudioEngine::StartL() 450 497 { 451 TInt err = iSession.Connect();452 if (err != KErrNone && err != KErrAlreadyExists)453 return err;454 455 498 if (state_ == STATE_READY) 456 499 return StartStreamL(); 457 500 458 // Even if only capturer are opened, playback thread of APS Server need 501 // Even if only capturer are opened, playback thread of APS Server need 459 502 // to be run(?). Since some messages will be delivered via play comm queue. 460 503 return InitPlayL(); … … 463 506 void CPjAudioEngine::Stop() 464 507 { 465 iSession.Stop(); 466 467 delete iRecHandler; 468 iRecHandler = NULL; 469 470 state_ = STATE_READY; 508 if (state_ == STATE_STREAMING) { 509 iSession.Stop(); 510 state_ = STATE_READY; 511 TRACE_((THIS_FILE, "Streaming stopped")); 512 } 471 513 } 472 514 473 515 void CPjAudioEngine::ConstructL() 474 516 { 475 iSettings.iFourCC = TFourCC(KMCPFourCCIdG711);476 i Settings.iGlobal = APP_UID;477 i Settings.iPriority = TMdaPriority(100);478 i Settings.iPreference = TMdaPriorityPreference(0x05210001);479 i Settings.iSettings.iChannels = EMMFMono;480 i Settings.iSettings.iSampleRate = EMMFSampleRate8000Hz;481 i Settings.iSettings.iVolume = 0;482 483 / * play_buf size is samples per frame of parent stream. */484 play_buf = (pj_int16_t*)pj_pool_alloc(parentStrm_->pool,485 parentStrm_->samples_per_frame << 1);486 play_buf_len = 0;487 play_buf_start = 0;488 489 /* rec_buf size is samples per frame of parent stream. */490 rec_buf = (pj_int16_t*)pj_pool_alloc(parentStrm_->pool,491 parentStrm_->samples_per_frame << 1); 492 rec_buf_len = 0;517 // Recorder settings 518 iRecSettings.iFourCC = setting_.fourcc; 519 iRecSettings.iGlobal = APP_UID; 520 iRecSettings.iPriority = TMdaPriority(100); 521 iRecSettings.iPreference = TMdaPriorityPreference(0x05210001); 522 iRecSettings.iSettings.iChannels = EMMFMono; 523 iRecSettings.iSettings.iSampleRate = EMMFSampleRate8000Hz; 524 525 // Player settings 526 iPlaySettings.iFourCC = setting_.fourcc; 527 iPlaySettings.iGlobal = APP_UID; 528 iPlaySettings.iPriority = TMdaPriority(100); 529 iPlaySettings.iPreference = TMdaPriorityPreference(0x05220001); 530 iPlaySettings.iSettings.iChannels = EMMFMono; 531 iPlaySettings.iSettings.iSampleRate = EMMFSampleRate8000Hz; 532 iPlaySettings.iSettings.iVolume = 0; 533 534 User::LeaveIfError(iSession.Connect()); 493 535 } 494 536 … … 498 540 return 0; 499 541 500 iSession.SetCng(EFalse); 501 iSession.SetVadMode(EFalse); 502 iSession.SetPlc(EFalse); 503 iSession.SetEncoderMode(EULawOr30ms); 504 iSession.SetDecoderMode(EULawOr30ms); 505 iSession.ActivateLoudspeaker(act_loudspeaker); 506 507 // Not only playback 508 if (parentStrm_->dir != PJMEDIA_DIR_PLAYBACK) { 509 iRecHandler = CQueueHandler::NewL(this, &iReadQ, 510 CQueueHandler::ERecordQueue); 511 iRecHandler->Start(); 512 iSession.Read(); 513 TRACE_((THIS_FILE, "APS recorder started")); 514 } 542 iSession.SetCng(setting_.cng); 543 iSession.SetVadMode(setting_.vad); 544 iSession.SetPlc(setting_.plc); 545 iSession.SetEncoderMode(setting_.mode); 546 iSession.SetDecoderMode(setting_.mode); 547 iSession.ActivateLoudspeaker(setting_.loudspk); 515 548 516 549 // Not only capture 517 550 if (parentStrm_->dir != PJMEDIA_DIR_CAPTURE) { 518 551 iSession.Write(); 519 TRACE_((THIS_FILE, "APS player started")); 552 TRACE_((THIS_FILE, "Player streaming started")); 553 } 554 555 // Not only playback 556 if (parentStrm_->dir != PJMEDIA_DIR_PLAYBACK) { 557 iSession.Read(); 558 TRACE_((THIS_FILE, "Recorder streaming started")); 520 559 } 521 560 … … 557 596 } 558 597 559 void CPjAudioEngine::RecCb(TAPSCommBuffer &buffer)560 {561 pj_assert(buffer.iBuffer[0] == 1 && buffer.iBuffer[1] == 0);562 563 /* Detect the recorder G.711 frame size, player frame size will follow564 * this recorder frame size.565 */566 if (CPjAudioEngine::aps_samples_per_frame == 0) {567 CPjAudioEngine::aps_samples_per_frame = buffer.iBuffer.Length() < 160?568 80 : 160;569 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples",570 CPjAudioEngine::aps_samples_per_frame));571 }572 573 /* Decode APS buffer (coded in G.711) and put the PCM result into rec_buf.574 * Whenever rec_buf is full, call parent stream callback.575 */576 unsigned dec_len = 0;577 578 while (dec_len < CPjAudioEngine::aps_samples_per_frame) {579 unsigned tmp;580 581 tmp = PJ_MIN(parentStrm_->samples_per_frame - rec_buf_len,582 CPjAudioEngine::aps_samples_per_frame - dec_len);583 pjmedia_ulaw_decode(&rec_buf[rec_buf_len],584 buffer.iBuffer.Ptr() + 2 + dec_len,585 tmp);586 rec_buf_len += tmp;587 dec_len += tmp;588 589 pj_assert(rec_buf_len <= parentStrm_->samples_per_frame);590 591 if (rec_buf_len == parentStrm_->samples_per_frame) {592 recCb_(userData_, 0, rec_buf, rec_buf_len << 1);593 rec_buf_len = 0;594 }595 }596 }597 598 void CPjAudioEngine::PlayCb(TAPSCommBuffer &buffer)599 {600 buffer.iCommand = CQueueHandler::EAPSPlayData;601 buffer.iStatus = 0;602 buffer.iBuffer.Zero();603 buffer.iBuffer.Append(1);604 buffer.iBuffer.Append(0);605 606 /* Send 10ms silence frame if frame size hasn't been known. */607 if (CPjAudioEngine::aps_samples_per_frame == 0) {608 pjmedia_zero_samples(play_buf, 80);609 pjmedia_ulaw_encode((pj_uint8_t*)play_buf, play_buf, 80);610 buffer.iBuffer.Append((TUint8*)play_buf, 80);611 iWriteQ.Send(buffer);612 return;613 }614 615 unsigned enc_len = 0;616 617 /* Call parent stream callback to get PCM samples to play,618 * encode the PCM samples into G.711 and put it into APS buffer.619 */620 while (enc_len < CPjAudioEngine::aps_samples_per_frame) {621 if (play_buf_len == 0) {622 playCb_(userData_, 0, play_buf, parentStrm_->samples_per_frame<<1);623 play_buf_len = parentStrm_->samples_per_frame;624 play_buf_start = 0;625 }626 627 unsigned tmp;628 629 tmp = PJ_MIN(play_buf_len,630 CPjAudioEngine::aps_samples_per_frame - enc_len);631 pjmedia_ulaw_encode((pj_uint8_t*)&play_buf[play_buf_start],632 &play_buf[play_buf_start],633 tmp);634 buffer.iBuffer.Append((TUint8*)&play_buf[play_buf_start], tmp);635 enc_len += tmp;636 play_buf_len -= tmp;637 play_buf_start += tmp;638 }639 640 iWriteQ.Send(buffer);641 }642 643 598 // 644 599 // End of inherited from MQueueHandlerObserver … … 650 605 if (state_ == STATE_READY || state_ == STATE_STREAMING) { 651 606 iSession.ActivateLoudspeaker(active); 607 TRACE_((THIS_FILE, "Loudspeaker on/off: %d", active)); 652 608 return KErrNone; 653 609 } … … 658 614 659 615 616 static void RecCbPcm(TAPSCommBuffer &buf, void *user_data) 617 { 618 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 619 620 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 621 622 /* Detect the recorder G.711 frame size, player frame size will follow 623 * this recorder frame size. 624 */ 625 if (aps_g711_frame_len == 0) { 626 aps_g711_frame_len = buf.iBuffer.Length() < 160? 80 : 160; 627 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 628 aps_g711_frame_len)); 629 } 630 631 /* Decode APS buffer (coded in G.711) and put the PCM result into rec_buf. 632 * Whenever rec_buf is full, call parent stream callback. 633 */ 634 unsigned dec_len = 0; 635 636 while (dec_len < aps_g711_frame_len) { 637 unsigned tmp; 638 639 tmp = PJ_MIN(strm->samples_per_frame - strm->rec_buf_len, 640 aps_g711_frame_len - dec_len); 641 pjmedia_ulaw_decode(&strm->rec_buf[strm->rec_buf_len], 642 buf.iBuffer.Ptr() + 2 + dec_len, 643 tmp); 644 strm->rec_buf_len += tmp; 645 dec_len += tmp; 646 647 pj_assert(strm->rec_buf_len <= strm->samples_per_frame); 648 649 if (strm->rec_buf_len == strm->samples_per_frame) { 650 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 651 strm->rec_buf_len << 1); 652 strm->rec_buf_len = 0; 653 } 654 } 655 } 656 657 static void PlayCbPcm(TAPSCommBuffer &buf, void *user_data) 658 { 659 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 660 unsigned g711_frame_len = aps_g711_frame_len; 661 662 buf.iCommand = CQueueHandler::EAPSPlayData; 663 buf.iStatus = 0; 664 buf.iBuffer.Zero(); 665 buf.iBuffer.Append(1); 666 buf.iBuffer.Append(0); 667 668 /* Assume frame size is 10ms if frame size hasn't been known. */ 669 if (g711_frame_len == 0) 670 g711_frame_len = 80; 671 672 /* Call parent stream callback to get PCM samples to play, 673 * encode the PCM samples into G.711 and put it into APS buffer. 674 */ 675 unsigned enc_len = 0; 676 while (enc_len < g711_frame_len) { 677 if (strm->play_buf_len == 0) { 678 strm->play_cb(strm->user_data, 0, strm->play_buf, 679 strm->samples_per_frame<<1); 680 strm->play_buf_len = strm->samples_per_frame; 681 strm->play_buf_start = 0; 682 } 683 684 unsigned tmp; 685 686 tmp = PJ_MIN(strm->play_buf_len, g711_frame_len - enc_len); 687 pjmedia_ulaw_encode((pj_uint8_t*)&strm->play_buf[strm->play_buf_start], 688 &strm->play_buf[strm->play_buf_start], 689 tmp); 690 buf.iBuffer.Append((TUint8*)&strm->play_buf[strm->play_buf_start], tmp); 691 enc_len += tmp; 692 strm->play_buf_len -= tmp; 693 strm->play_buf_start += tmp; 694 } 695 } 696 697 static void RecCb(TAPSCommBuffer &buf, void *user_data) 698 { 699 } 700 701 static void PlayCb(TAPSCommBuffer &buf, void *user_data) 702 { 703 } 704 660 705 /* 661 706 * Initialize sound subsystem. … … 664 709 { 665 710 snd_pool_factory = factory; 711 712 def_setting.format.u32 = PJMEDIA_FOURCC_L16; 713 def_setting.mode = 0; 714 def_setting.bitrate = 128000; 715 def_setting.plc = PJ_FALSE; 716 def_setting.vad = PJ_FALSE; 717 def_setting.cng = PJ_FALSE; 718 def_setting.loudspk = PJ_FALSE; 719 666 720 return PJ_SUCCESS; 667 721 } … … 701 755 pj_pool_t *pool; 702 756 pjmedia_snd_stream *strm; 757 CPjAudioSetting setting; 758 PjAudioCallback aps_rec_cb; 759 PjAudioCallback aps_play_cb; 703 760 704 761 PJ_ASSERT_RETURN(p_snd_strm, PJ_EINVAL); 705 PJ_ASSERT_RETURN(clock_rate == 8000 && channel_count == 1 && 762 PJ_ASSERT_RETURN(clock_rate == 8000 && channel_count == 1 && 706 763 bits_per_sample == 16, PJ_ENOTSUP); 707 764 PJ_ASSERT_RETURN((dir == PJMEDIA_DIR_CAPTURE_PLAYBACK && rec_cb && play_cb) … … 710 767 PJ_EINVAL); 711 768 712 pool = pj_pool_create(snd_pool_factory, POOL_NAME, POOL_SIZE, POOL_INC, 769 pool = pj_pool_create(snd_pool_factory, POOL_NAME, POOL_SIZE, POOL_INC, 713 770 NULL); 714 771 if (!pool) 715 772 return PJ_ENOMEM; 716 773 717 strm = (pjmedia_snd_stream*) pj_pool_zalloc(pool, 774 strm = (pjmedia_snd_stream*) pj_pool_zalloc(pool, 718 775 sizeof(pjmedia_snd_stream)); 719 776 strm->dir = dir; … … 723 780 strm->samples_per_frame = samples_per_frame; 724 781 782 /* Set audio engine settings. */ 783 if (def_setting.format.u32 == PJMEDIA_FOURCC_G711U || 784 def_setting.format.u32 == PJMEDIA_FOURCC_L16) 785 { 786 setting.fourcc = TFourCC(KMCPFourCCIdG711); 787 } else { 788 setting.fourcc = TFourCC(def_setting.format.u32); 789 } 790 791 if (def_setting.format.u32 == PJMEDIA_FOURCC_AMR) 792 { 793 setting.mode = (TAPSCodecMode)def_setting.bitrate; 794 } else if (def_setting.format.u32 == PJMEDIA_FOURCC_G711U || 795 def_setting.format.u32 == PJMEDIA_FOURCC_L16 || 796 (def_setting.format.u32 == PJMEDIA_FOURCC_ILBC && 797 def_setting.mode == 30)) 798 { 799 setting.mode = EULawOr30ms; 800 } else { 801 setting.mode = EALawOr20ms; 802 } 803 804 setting.vad = def_setting.vad; 805 setting.plc = def_setting.plc; 806 setting.cng = def_setting.cng; 807 setting.loudspk = def_setting.loudspk; 808 809 if (def_setting.format.u32 == PJMEDIA_FOURCC_AMR || 810 def_setting.format.u32 == PJMEDIA_FOURCC_G711A || 811 def_setting.format.u32 == PJMEDIA_FOURCC_G711U || 812 def_setting.format.u32 == PJMEDIA_FOURCC_G729 || 813 def_setting.format.u32 == PJMEDIA_FOURCC_ILBC) 814 { 815 aps_play_cb = &PlayCb; 816 aps_rec_cb = &RecCb; 817 } else { 818 aps_play_cb = &PlayCbPcm; 819 aps_rec_cb = &RecCbPcm; 820 } 821 725 822 // Create the audio engine. 726 TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, rec_cb, play_cb, 727 user_data)); 823 TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, 824 aps_rec_cb, aps_play_cb, 825 strm, setting)); 728 826 if (err != KErrNone) { 729 pj_pool_release(pool); 827 pj_pool_release(pool); 730 828 return PJ_RETURN_OS_ERROR(err); 731 829 } 830 831 strm->rec_cb = rec_cb; 832 strm->play_cb = play_cb; 833 strm->user_data = user_data; 834 835 /* play_buf size is samples per frame. */ 836 strm->play_buf = (pj_int16_t*)pj_pool_alloc(pool, samples_per_frame << 1); 837 strm->play_buf_len = 0; 838 strm->play_buf_start = 0; 839 840 /* rec_buf size is samples per frame. */ 841 strm->rec_buf = (pj_int16_t*)pj_pool_alloc(pool, samples_per_frame << 1); 842 strm->rec_buf_len = 0; 732 843 733 844 // Done. … … 753 864 PJ_ASSERT_RETURN(index == 0, PJ_EINVAL); 754 865 755 return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, 866 return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, 756 867 samples_per_frame, bits_per_sample, rec_cb, NULL, 757 868 user_data, p_snd_strm); … … 770 881 PJ_ASSERT_RETURN(index == 0, PJ_EINVAL); 771 882 772 return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, 883 return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, 773 884 samples_per_frame, bits_per_sample, NULL, play_cb, 774 885 user_data, p_snd_strm); … … 790 901 PJ_ASSERT_RETURN(play_id == 0 && rec_id == 0, PJ_EINVAL); 791 902 792 return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, 903 return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, 793 904 samples_per_frame, bits_per_sample, rec_cb, play_cb, 794 905 user_data, p_snd_strm); … … 822 933 { 823 934 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 824 935 825 936 if (stream->engine) { 826 937 TInt err = stream->engine->StartL(); … … 828 939 return PJ_RETURN_OS_ERROR(err); 829 940 } 830 941 831 942 return PJ_SUCCESS; 832 943 } … … 836 947 { 837 948 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 838 949 839 950 if (stream->engine) { 840 951 stream->engine->Stop(); 841 952 } 842 953 843 954 return PJ_SUCCESS; 844 955 } … … 848 959 { 849 960 pj_pool_t *pool; 850 961 851 962 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 852 853 if (stream->engine) { 854 delete stream->engine; 855 stream->engine = NULL; 856 } 963 964 delete stream->engine; 965 stream->engine = NULL; 857 966 858 967 pool = stream->pool; 859 if (pool) { 968 if (pool) { 860 969 stream->pool = NULL; 861 970 pj_pool_release(pool); 862 971 } 863 972 864 973 return PJ_SUCCESS; 865 974 } … … 876 985 * Set sound latency. 877 986 */ 878 PJ_DEF(pj_status_t) pjmedia_snd_set_latency(unsigned input_latency, 987 PJ_DEF(pj_status_t) pjmedia_snd_set_latency(unsigned input_latency, 879 988 unsigned output_latency) 880 989 { … … 890 999 */ 891 1000 PJ_DEF(pj_status_t) pjmedia_snd_aps_activate_loudspeaker( 892 pjmedia_snd_stream *stream, 1001 pjmedia_snd_stream *stream, 893 1002 pj_bool_t active) 894 1003 { 895 1004 if (stream == NULL) { 896 act_loudspeaker= active;1005 def_setting.loudspk = active; 897 1006 } else { 898 1007 if (stream->engine == NULL) … … 906 1015 return PJ_SUCCESS; 907 1016 } 1017 1018 /** 1019 * Set a codec and its settings to be used on the next sound device session. 1020 */ 1021 PJ_DEF(pj_status_t) pjmedia_snd_aps_modify_setting( 1022 const pjmedia_snd_aps_setting *setting) 1023 { 1024 PJ_ASSERT_RETURN(setting, PJ_EINVAL); 1025 1026 def_setting = *setting; 1027 1028 return PJ_SUCCESS; 1029 } 1030 1031 #endif // PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_SYMB_APS_SOUND -
pjproject/branches/projects/aps-direct/pjsip-apps/src/symsndtest/app_main.cpp
r2394 r2434 50 50 51 51 PJ_UNUSED_ARG(level); 52 52 53 53 pj_ansi_to_unicode(buf, len, buf16, PJ_ARRAY_SIZE(buf16)); 54 54 … … 58 58 59 59 /* perror util */ 60 static void app_perror(const char *title, pj_status_t status) 61 { 62 char errmsg[PJ_ERR_MSG_SIZE]; 60 static void app_perror(const char *title, pj_status_t status) 61 { 62 char errmsg[PJ_ERR_MSG_SIZE]; 63 63 pj_strerror(status, errmsg, sizeof(errmsg)); 64 64 PJ_LOG(1,(THIS_FILE, "Error: %s: %s", title, errmsg)); … … 66 66 67 67 /* Application init */ 68 static pj_status_t app_init() 68 static pj_status_t app_init() 69 69 { 70 70 unsigned i, count; 71 71 pj_status_t status; 72 72 73 73 /* Redirect log */ 74 74 pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer); 75 75 pj_log_set_decor(PJ_LOG_HAS_NEWLINE); 76 76 pj_log_set_level(3); 77 77 78 78 /* Init pjlib */ 79 79 status = pj_init(); … … 84 84 85 85 pj_caching_pool_init(&cp, NULL, 0); 86 86 87 87 /* Init sound subsystem */ 88 88 status = pjmedia_snd_init(&cp.factory); … … 93 93 return status; 94 94 } 95 95 96 96 count = pjmedia_snd_get_dev_count(); 97 97 PJ_LOG(3,(THIS_FILE, "Device count: %d", count)); 98 98 for (i=0; i<count; ++i) { 99 99 const pjmedia_snd_dev_info *info; 100 100 101 101 info = pjmedia_snd_get_dev_info(i); 102 102 PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz", 103 103 i, info->name, info->input_count, info->output_count, 104 info->default_samples_per_sec)); 104 info->default_samples_per_sec)); 105 105 } 106 106 … … 115 115 116 116 /* Init delay buffer */ 117 status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE, 118 SAMPLES_PER_FRAME, CHANNEL_COUNT, 117 status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE, 118 SAMPLES_PER_FRAME, CHANNEL_COUNT, 119 119 0, 0, &delaybuf); 120 120 if (status != PJ_SUCCESS) { … … 124 124 //return status; 125 125 } 126 126 127 127 return PJ_SUCCESS; 128 128 } … … 130 130 131 131 /* Sound capture callback */ 132 static pj_status_t rec_cb(void *user_data, 132 static pj_status_t rec_cb(void *user_data, 133 133 pj_uint32_t timestamp, 134 134 void *input, 135 unsigned size) 135 unsigned size) 136 136 { 137 137 PJ_UNUSED_ARG(user_data); … … 154 154 pj_uint32_t timestamp, 155 155 void *output, 156 unsigned size) 156 unsigned size) 157 157 { 158 158 PJ_UNUSED_ARG(user_data); 159 159 PJ_UNUSED_ARG(timestamp); 160 160 PJ_UNUSED_ARG(size); 161 161 162 162 pjmedia_delay_buf_get(delaybuf, (pj_int16_t*)output); 163 163 164 164 ++play_cnt; 165 return PJ_SUCCESS; 165 return PJ_SUCCESS; 166 166 } 167 167 168 168 /* Start sound */ 169 static pj_status_t snd_start(unsigned flag) 169 static pj_status_t snd_start(unsigned flag) 170 170 { 171 171 pj_status_t status; 172 172 173 173 if (strm != NULL) { 174 174 app_perror("snd already open", PJ_EINVALIDOP); 175 175 return PJ_EINVALIDOP; 176 176 } 177 177 178 178 if (flag==PJMEDIA_DIR_CAPTURE_PLAYBACK) 179 179 status = pjmedia_snd_open(-1, -1, CLOCK_RATE, CHANNEL_COUNT, … … 188 188 SAMPLES_PER_FRAME, BITS_PER_SAMPLE, 189 189 &play_cb, NULL, &strm); 190 190 191 191 if (status != PJ_SUCCESS) { 192 192 app_perror("snd open", status); … … 211 211 212 212 /* Stop sound */ 213 static pj_status_t snd_stop() 213 static pj_status_t snd_stop() 214 214 { 215 215 pj_time_val now; 216 216 pj_status_t status; 217 217 218 218 if (strm == NULL) { 219 219 app_perror("snd not open", PJ_EINVALIDOP); 220 220 return PJ_EINVALIDOP; 221 221 } 222 222 223 status = pjmedia_snd_stream_stop(strm); 224 if (status != PJ_SUCCESS) { 225 app_perror("snd failed to stop", status); 226 } 223 227 status = pjmedia_snd_stream_close(strm); 224 228 strm = NULL; 225 229 226 230 pj_gettimeofday(&now); 227 231 PJ_TIME_VAL_SUB(now, t_start); … … 235 239 236 240 /* Shutdown application */ 237 static void app_fini() 241 static void app_fini() 238 242 { 239 243 if (strm) 240 244 snd_stop(); 241 245 242 246 pjmedia_snd_deinit(); 243 247 pjmedia_delay_buf_destroy(delaybuf); … … 254 258 #include <e32base.h> 255 259 256 class ConsoleUI : public CActive 260 class ConsoleUI : public CActive 257 261 { 258 262 public: 259 ConsoleUI(C ActiveSchedulerWait *asw, CConsoleBase *con);263 ConsoleUI(CConsoleBase *con); 260 264 261 265 // Run console UI … … 264 268 // Stop 265 269 void Stop(); 266 270 267 271 protected: 268 272 // Cancel asynchronous read. … … 271 275 // Implementation: called when read has completed. 272 276 void RunL(); 273 277 274 278 private: 275 CActiveSchedulerWait *asw_;276 279 CConsoleBase *con_; 277 280 }; 278 281 279 282 280 ConsoleUI::ConsoleUI(C ActiveSchedulerWait *asw, CConsoleBase *con)281 : CActive(EPriority High), asw_(asw), con_(con)283 ConsoleUI::ConsoleUI(CConsoleBase *con) 284 : CActive(EPriorityUserInput), con_(con) 282 285 { 283 286 CActiveScheduler::Add(this); … … 285 288 286 289 // Run console UI 287 void ConsoleUI::Run() 290 void ConsoleUI::Run() 288 291 { 289 292 con_->Read(iStatus); … … 292 295 293 296 // Stop console UI 294 void ConsoleUI::Stop() 297 void ConsoleUI::Stop() 295 298 { 296 299 DoCancel(); … … 298 301 299 302 // Cancel asynchronous read. 300 void ConsoleUI::DoCancel() 303 void ConsoleUI::DoCancel() 301 304 { 302 305 con_->ReadCancel(); 303 306 } 304 307 305 static void PrintMenu() 308 static void PrintMenu() 306 309 { 307 310 PJ_LOG(3, (THIS_FILE, "\n\n" … … 315 318 316 319 // Implementation: called when read has completed. 317 void ConsoleUI::RunL() 320 void ConsoleUI::RunL() 318 321 { 319 322 TKeyCode kc = con_->KeyCode(); 320 323 pj_bool_t reschedule = PJ_TRUE; 321 324 322 325 switch (kc) { 323 326 case 'w': 324 asw_->AsyncStop(); 327 snd_stop(); 328 CActiveScheduler::Stop(); 325 329 reschedule = PJ_FALSE; 326 330 break; … … 344 348 345 349 PrintMenu(); 346 350 347 351 if (reschedule) 348 352 Run(); … … 351 355 352 356 //////////////////////////////////////////////////////////////////////////// 353 int app_main() 357 int app_main() 354 358 { 355 359 if (app_init() != PJ_SUCCESS) 356 360 return -1; 357 361 358 362 // Run the UI 359 CActiveSchedulerWait *asw = new CActiveSchedulerWait; 360 ConsoleUI *con = new ConsoleUI(asw, console); 361 363 ConsoleUI *con = new ConsoleUI(console); 364 362 365 con->Run(); 363 366 364 367 PrintMenu(); 365 asw->Start();366 368 CActiveScheduler::Start(); 369 367 370 delete con; 368 delete asw; 369 371 370 372 app_fini(); 371 373 return 0; -
pjproject/branches/projects/aps-direct/pjsip-apps/src/symsndtest/main_symbian.cpp
r2394 r2434 30 30 31 31 // Needed by APS 32 TPtrC APP_UID = _L("A000000 D");32 TPtrC APP_UID = _L("A000000E"); 33 33 34 34 int app_main(); 35 35 36 37 ////////////////////////////////////////////////////////////////////////////38 class MyTask : public CActive39 {40 public:41 static MyTask *NewL(CActiveSchedulerWait *asw);42 ~MyTask();43 void Start();44 45 protected:46 MyTask(CActiveSchedulerWait *asw);47 void ConstructL();48 virtual void RunL();49 virtual void DoCancel();50 51 private:52 RTimer timer_;53 CActiveSchedulerWait *asw_;54 };55 56 MyTask::MyTask(CActiveSchedulerWait *asw)57 : CActive(EPriorityNormal), asw_(asw)58 {59 }60 61 MyTask::~MyTask()62 {63 timer_.Close();64 }65 66 void MyTask::ConstructL()67 {68 timer_.CreateLocal();69 CActiveScheduler::Add(this);70 }71 72 MyTask *MyTask::NewL(CActiveSchedulerWait *asw)73 {74 MyTask *self = new (ELeave) MyTask(asw);75 CleanupStack::PushL(self);76 77 self->ConstructL();78 79 CleanupStack::Pop(self);80 return self;81 }82 83 void MyTask::Start()84 {85 timer_.After(iStatus, 0);86 SetActive();87 }88 89 void MyTask::RunL()90 {91 int rc = app_main();92 asw_->AsyncStop();93 }94 95 void MyTask::DoCancel()96 {97 98 }99 36 100 37 //////////////////////////////////////////////////////////////////////////// … … 106 43 CActiveScheduler::Install(scheduler); 107 44 108 CActiveSchedulerWait *asw = new CActiveSchedulerWait; 109 CleanupStack::PushL(asw); 110 111 MyTask *task = MyTask::NewL(asw); 112 task->Start(); 45 app_main(); 113 46 114 asw->Start();115 116 delete task;117 118 CleanupStack::Pop(asw);119 delete asw;120 121 47 CActiveScheduler::Install(NULL); 122 48 CleanupStack::Pop(scheduler); … … 143 69 TRAPD(startError, DoStartL()); 144 70 145 console->Printf(_L("[press any key to close]\n"));146 console->Getch();147 71 //console->Printf(_L("[press any key to close]\n")); 72 //console->Getch(); 73 148 74 delete console; 149 75 delete cleanup; 150 76 151 CloseSTDLIB(); 77 CloseSTDLIB(); 152 78 153 79 // Mark end of heap usage, detect memory leaks
Note: See TracChangeset
for help on using the changeset viewer.