User Tools

Site Tools


en:tutorials:audio:sound-recording

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:orx:tutorials:community:tdomhan:sound-recording [2010/12/09 10:13 (13 years ago)] – Minor alignment update iarwainen:tutorials:audio:sound-recording [2022/03/27 13:42 (2 years ago)] (current) – Removed OpenAL reference iarwain
Line 2: Line 2:
  
 ===== Prerequisites ===== ===== Prerequisites =====
-Right now you need the **sound recording branch** of orx in order to actually be able to record sound. However this is subject too change in the next couple of weeks. You can find the branch in the project's SVN repository: http://orx.svn.sourceforge.net/viewvc/orx/branches/SoundRecording/\\ +Right now you need the svn version of orx in order to actually be able to record sound. However this is subject too change in the next couple of weeks. You can find it at:\\ 
-Furthermore sound capturing is only implemented in the OpenAL sound plugin right now. We will now present some basic recipes for common tasks and then cover the advanced settings and the whole API later.+http://orx.svn.sourceforge.net/viewvc/orx/trunk
 + 
 +We will now present some basic recipes for common tasks and then cover the advanced settings and the whole API later.
  
 ===== Capturing audio data to a file ===== ===== Capturing audio data to a file =====
 So let's say all you want to do is to capture some audio data from the default input device into a file. This is fairly easy and can be done like this: So let's say all you want to do is to capture some audio data from the default input device into a file. This is fairly easy and can be done like this:
 <code c> <code c>
-  orxSOUNDSYSTEM_RECORD_INFO record_info; +  // Let's start recording: 
-  record_info.u32ChannelNumber = 1;                  //number of channels, either 1 or 2 +  orxSound_StartRecording("sound.wav", orxTRUE, 44100, 1)
-  record_info.u32SampleRate = 44100;                 //leave the sample rate like this unless you know what you're doing +  // _zName = "sound.wav", that's the name of the file where the captured audio samples will be written 
-  record_info.bCustomPollingFrequency = orxFALSE;    //this feature will be covered later +  // Its extension determines which file format will be used for compression. 
-  record_info.bFixedBlockSize = orxFALSE;            //this feature will be covered later +  // _bWriteToFile = orxTRUE: we'll start writing to file immediately 
-  //now let'start recording+  // _u32SampleRate = 4410044100 samples will be recorded per second 
-  orxSoundSystem_StartRecordingToFile("sound.wav","sound", &record_info);+  // _u32ChannelRate = 1 : the audio data will be mono
 </code> </code>
-Now a file sound.wav will be created and recorded to. The format is always [[http://en.wikipedia.org/wiki/WAV|WAV]]. Once you think you have captured enough data you can stop recording like this:+sound.wav file will be created and recorded to. The format depends on the extension, here it'[[http://en.wikipedia.org/wiki/WAV|WAV]].\\ 
 +The supported file extensions/formats are: WAV, CAF, VOC, AIFF, AU/SND, IFF/SVX. If the file extension is none of these, RAW (ie. uncompressed) samples will be written. 
 + 
 +You can decide if you want to write the recorded data to the file with _bWriteToFile = orxTRUE/orxFALSE. We'll see later how to decide this on a per packet basis. 
 + 
 +Passing 0 to _u32SampleRate and/or _u32ChannelNumber will use orx's default values for them. Defaults values are 44100Hz for the sampling rate and mono for the channel number. 
 + 
 +Once you think you have captured enough data you can stop recording like this:
 <code c> <code c>
-  orxSoundSystem_StopRecording();+  orxSound_StopRecording();
 </code> </code>
-**warning:** //orxSoundSystem_StopRecordingToFile// will stop capturing to that file, but will not stop the actual sound capturing! 
  
 ===== Processing audio data ===== ===== Processing audio data =====
-Let's say you want to do some fancy processing of the audio data, instead of recording it to a file. First we need to register a event handler, that will receive the raw audio data:+Let'now say you want to do some fancy processing of the audio data, before or instead of recording it to a file. 
 + 
 +First we need an event handler, that will receive the raw audio samples:
 <code c> <code c>
 static orxSTATUS orxFASTCALL SoundProcessingHandler(const orxEVENT *event)  static orxSTATUS orxFASTCALL SoundProcessingHandler(const orxEVENT *event) 
Line 32: Line 42:
       switch(event->eID)       switch(event->eID)
       {       {
-        case orxSOUND_EVENT_RECORD_PACKET:+        case orxSOUND_EVENT_RECORDING_PACKET:
           {           {
             orxSOUND_EVENT_PAYLOAD* payload = (orxSOUND_EVENT_PAYLOAD*)event->pstPayload;             orxSOUND_EVENT_PAYLOAD* payload = (orxSOUND_EVENT_PAYLOAD*)event->pstPayload;
-            some_fancy_library_process(payload ->stRecordPacket.au16SampleArray, payload->stRecordPacket.u32SampleNumber, payload->stRecordPacket.dTimestamp);+            some_fancy_library_process(payload->stRecording.stPacket.as16SampleList, payload->stRecording.stPacket.u32SampleNumber, payload->stRecording.stPacket.fTimestamp); 
 +             
 +            payload->stRecording.stPacket.bWriteToFile = (some_fancy_test? orxTRUE : orxFALSE;
           }           }
           break;           break;
-        case orxSOUND_EVENT_RECORD_START:+        case orxSOUND_EVENT_RECORDING_START:
           some_fancy_library_initialize();           some_fancy_library_initialize();
           break;           break;
-        case orxSOUND_EVENT_RECORD_STOP:+        case orxSOUND_EVENT_RECORDING_STOP:
           some_fancy_library_finalize();           some_fancy_library_finalize();
           break;           break;
Line 61: Line 73:
 Now we can start to capture audio samples: Now we can start to capture audio samples:
 <code c> <code c>
-  orxSOUNDSYSTEM_RECORD_INFO record_info; 
-  record_info.u32ChannelNumber = 1;                  //number of channels, either 1 or 2 
-  record_info.u32SampleRate = 44100;                 //leave the sample rate like this unless you know what you're doing 
-  record_info.bCustomPollingFrequency = orxFALSE;    //this feature will be covered later 
-  record_info.bFixedBlockSize = orxFALSE;            //this feature will be covered later 
   //now let's start recording:   //now let's start recording:
-  orxSoundSystem_StartRecording("sound", &record_info);+  orxSound_StartRecording("sound.wav", orxFALSE, 0, 0);
 </code> </code>
-Afterwards first an event of the type orxSOUND_EVENT_RECORD_START will be created. After that each time new audio data is available an event of the type orxSOUND_EVENT_RECORD_PACKET will be created. You can access the raw audio data through the payload of the event. Beside the audio data it also contains the number of samples that were captured and the time at which the current samples were recorded(in seconds since starting the application). More precisely it's the timestamp of the first sample in the current package. Each audio sample is represented by a 16bit integer value.   +Afterwards, the first event our handler will receive has a orxSOUND_EVENT_RECORDING_START ID. After thateach time new audio data is availablean event of orxSOUND_EVENT_RECORDING_PACKET ID will be created. You can access the raw audio data through the payload of the event. Beside the audio data it also contains the number of samples that were captured and the time at which the current samples were recorded(in seconds since starting the application). More precisely it's the timestamp of the first sample in the current package. Each audio sample is represented by a 16bit integer value, ranging from -32768 to 32767, 0 being an audio output level of zero. 
-Once we are done we stop the capturing:+ 
 +Once again, when we are done we stop the capturing with:
 <code c> <code c>
-  orxSoundSystem_StopRecording();+  orxSound_StopRecording();
 </code> </code>
-Which will be followed by a orxSOUND_EVENT_RECORD_STOP event.+Which will be followed by a orxSOUND_EVENT_RECORDING_STOP event.
  
 ===== Doing both: Capturing to a file  and processing the audio data ===== ===== Doing both: Capturing to a file  and processing the audio data =====
-So what if we want to do both, capturing the data to a file and process it at the same time? Well that's not a problem. After calling orxSoundSystem_StartRecordingToFile the same events(containing the raw audio data), as described in the previous section, will be created. If you don't want to start both at the same time, meaning like you want to process the audio data the whole time but you want to record to a file only temporarily, you can just call orxSoundSystem_StartRecording at first and once you want to record to a file call orxSoundSystem_StartRecordingToFile. Once you are done capturing to a file just call orxSoundSystem_StopRecordingToFile. This will not stop the actual capturing, but just the recording to the file. Calling orxSoundSystem_StartRecording will **both** capturing and recording to a file!+So what if we want to do both, capturing the data to a file and process it at the same time? Well that's not a problem.
  
 +We can specify for each sound packet if it needs to be recorded or not by changing payload->stRecording.stPacket.bWriteToFile.
  
-===== Advanced settings explained ===== +We can also alter the samples directly in the payload array (payload->stRecording.stPacket.as16SampleList). 
-So what are those advanced settings about? There are basically two advanced settings: the **polling frequency** and the **fixed block size**. The polling frequency will determine how often the audio hardware is polled for new audio data. This means the higher the frequency is the less is the latency of the capturing. However if it is too high you will waste CPU timebecause the likelihood that no data is available yet increases. So use this setting only if you really need it. By default everytime there is new audio data, no matter how many samples, an orxSOUND_EVENT_RECORD_PACKET event will be raised. This does not necessarily mean that, e.g. there will be an event for something like just 1 sample, because of hardware/driver limitationsIf you don'want this behavior or if you always want the same number of samples you may specify fixed block size+If we want to use less samples, we need also to update their number (payload->stRecording.stPacket.u32SampleNumber). 
 + 
 +If we need more space for our samples, we can't reuse the array pointed by the payload. Instead we can populate our own array and update the payload pointer and the sample number accordingly. 
 + 
 +**NB: We can't use a stack allocated array for this as the array has to be valid till the next sound event we receive in our handler. 
 +If we allocated dynamically this array, we'll be in charge of deleting when receiving a future sound event so as to not leak any memory.** 
 + 
 +===== Advanced technique ===== 
 + 
 +If we need more advanced setting such as only analyzing sound blocks of a given size, we can make a local copy in a buffer till we receive the correct amoung of data. 
 +//NB: We can then process it, modify it if needed and ask for it to be written to file if needs be. One can'assume the number of samples sent by orx will ever be constant or sent at constant time interval.//
  
  
Line 87: Line 106:
 Here is an overview of the API, until the doxygen documentation is updated: Here is an overview of the API, until the doxygen documentation is updated:
 <code c> <code c>
-/** Sound system record info+/** Sound recording info
  */  */
-typedef struct __orxSOUNDSYSTEM_RECORD_INFO_t+typedef struct __orxSOUND_RECORDING_INFO_t
 { {
-  orxU32                      u32SampleRate;           /**< The sample rate, e.g. 44100 Hertz */ +  orxU32    u32SampleRate;                    /**< The sample rate, e.g. 44100 Hertz : 4 */ 
-  orxU32                      u32ChannelNumber;        /**< Number of channelseither mono(1) or stereo (2) */ +  orxU32    u32ChannelNumber;                 /**< Number of channelseither mono (1) or stereo (2) : 8 */
-  orxBOOL                     bCustomPollingFrequency; /**< Do you need a specific polling freq? (Usually you don't!) */ +
-  orxFLOAT                    dPollingFrequency;       /**< The frequency at which the audio capturing device is polled. HighFreq = low latency. Be careful when also using a fixed block size. */ +
-  orxBOOL                     bFixedBlockSize;         /**< Shall the audio data be fetched from the device in blocks of a fixed size? Only use it when you really need it! */ +
-  orxU32                      u32BlockSize;            /**< Fixed number of samples that will be fetched at each poll. */ +
-} orxSOUNDSYSTEM_RECORD_INFO;+
  
-/** Starts recording +} orxSOUND_RECORDING_INFO; 
- * @param[in]   _zName                                Name for the recorded sound + 
- * @param[in]   _pstInfo                              Recording information +/** Sound recording packet
- * @return orxSTATUS_SUCCESS / orxSTATSUS_FAILURE+
  */  */
-orxSTATUS orxSoundSystem_StartRecording(const orxCHAR *_zName, const orxSOUNDSYSTEM_RECORD_INFO *_pstInfo);+typedef struct __orxSOUND_RECORDING_PACKET_t 
 +
 +  orxBOOL   bWriteToFile;                     /**< Write recording to sound file? : 4 */ 
 +  orxU32    u32SampleNumber                 /**< Number of samples contained in this packet : 8 */ 
 +  orxS16   *as16SampleList;                   /**< List of samples for this packet : 12 */ 
 +  orxFLOAT  fTimeStamp;                       /**< Packet's timestamp : 16 */
  
-/** Stops recording +} orxSOUND_RECORDING_PACKET; 
- * @return orxSTATUS_SUCCESS / orxSTATSUS_FAILURE+ 
 +/** Sound event payload
  */  */
-orxSTATUS orxSoundSystem_StopRecording();+typedef struct __orxSOUND_EVENT_PAYLOAD_t 
 +
 +  const orxSTRING               zSoundName  /**< Sound name : 4 */
  
-/** Is recording possbile on the current system?+  union 
 +  { 
 +    orxSOUND                   *pstSound;     /**< Sound reference : 8 */ 
 + 
 +    struct 
 +    { 
 +      orxSOUND_RECORDING_INFO   stInfo;       /**< Sound record info : 16 */ 
 +      orxSOUND_RECORDING_PACKET stPacket;     /**< Sound record packet : 24 */ 
 +    } stRecording; 
 +  };                                          /**< Recording : 24 */ 
 + 
 +} orxSOUND_EVENT_PAYLOAD; 
 + 
 +/** Starts recording 
 + * @param[in]   _zName                                Name for the recorded sound/file 
 + * @param[in]   _bWriteToFile                         Should write to file? 
 + * @param[in]   _u32SampleRate                        Sample rate, 0 for default rate (44100Hz) 
 + * @param[in]   _u32ChannelNumber                     Channel number, 0 for default mono channel 
 + * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE
  */  */
-orxBOOL orxSoundSystem_RecordingAvailable();+extern orxDLLAPI orxSTATUS orxFASTCALL                orxSound_StartRecording(const orxCHAR *_zName, orxBOOL _bWriteToFile, orxU32 _u32SampleRate, orxU32 _u32ChannelNumber);
  
-/** Starts recording to a file. orxSoundSystem_StartRecording might have been called before, but it's not mandatory. +/** Stops recording 
- * @param[in]   _zFileName                            Name of the resulting audio file. + * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE
- * @param[in]   _zName                                Name for the recorded sound +
- * @param[in]   _pstInfo                              Recording information +
- * @return orxSTATUS_SUCCESS / orxSTATSUS_FAILURE+
  */  */
-orxSTATUS orxSoundSystem_StartRecordingToFile(const orxCHAR *_zFileName, const orxCHAR *_zName, const orxSOUNDSYSTEM_RECORD_INFO *_pstInfo);+extern orxDLLAPI orxSTATUS orxFASTCALL                orxSound_StopRecording();
  
-/** Stops recording to a file. Does not stop the actual capturing! If you want to stop all capturing use orxSoundSystem_StopRecording instead. +/** Is recording possible on the current system? 
- * @return orxSTATUS_SUCCESS orxSTATSUS_FAILURE+ * @return orxTRUE orxFALSE
  */  */
-orxSTATUS orxSoundSystem_StopRecordingToFile();+extern orxDLLAPI orxBOOL orxFASTCALL                  orxSound_HasRecordingSupport();
  
 </code> </code>
en/tutorials/audio/sound-recording.1291918397.txt.gz · Last modified: 2017/05/30 00:50 (7 years ago) (external edit)