Update of /cvsroot/playerstage/code/player/server/drivers/audio
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27232/drivers/audio

Modified Files:
        alsa.cc alsa.h audio_sample.cc audio_sample.h 
Log Message:
Added support for PLAYER_AUDIO_SAMPLE_REC_REQ message. Added ability to filter 
mixer channels list. Improved recording logic.


Index: audio_sample.cc
===================================================================
RCS file: 
/cvsroot/playerstage/code/player/server/drivers/audio/audio_sample.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** audio_sample.cc     16 Jul 2006 02:50:08 -0000      1.1
--- audio_sample.cc     12 Feb 2007 01:30:14 -0000      1.2
***************
*** 25,28 ****
--- 25,31 ----
  
  #include <stdlib.h>
+ #include <iostream>
+ 
+ using namespace std;
  
  
////////////////////////////////////////////////////////////////////////////////
***************
*** 51,54 ****
--- 54,119 ----
  }
  
+ // Constructor from Player type
+ AudioSample::AudioSample (const player_audio_wav_t *source)
+ {
+       // Set the sample type to none
+       type = SAMPLE_TYPE_NONE;
+       // Blank wave data
+       numChannels = 0;
+       sampleRate = 0;
+       byteRate = 0;
+       blockAlign = 0;
+       bitsPerSample = 0;
+       numFrames = 0;
+       // Blank storage variables
+       position = 0;
+       waveFile = NULL;
+       filePath = NULL;
+       headerSize = 0;
+       dataLength = 0;
+       data = NULL;
+ 
+       if (!FromPlayer (source))
+               PLAYER_ERROR ("unable to create audio sample from Player data");
+ }
+ 
+ // Constructor from raw data
+ // source: the data to copy from
+ // length: number of _bytes_ in the data (not frames)
+ // channels: number of channels in the data
+ // sr: sample rate
+ // bps: bits per sample (8, 16, etc)
+ AudioSample::AudioSample (const uint8_t *source, uint32_t length, uint16_t 
channels, uint32_t sr, uint16_t bps)
+ {
+       // Set the sample type to memory
+       type = SAMPLE_TYPE_MEM;
+       // Set wave info
+       numChannels = channels;
+       sampleRate = sr;
+       bitsPerSample = bps;
+       // Calculate the other format info
+       blockAlign = numChannels * (bitsPerSample / 8);
+       byteRate = sampleRate * blockAlign;
+ 
+       // Blank other storage variables
+       position = 0;
+       waveFile = NULL;
+       filePath = NULL;
+       headerSize = 0;
+       dataLength = 0;
+       data = NULL;
+ 
+       // Allocate memory for the data
+       if ((data = new uint8_t[length]) == NULL)
+       {
+               PLAYER_ERROR ("Failed to allocate memory for wave data");
+               return;
+       }
+       // Copy the wave data across
+       memcpy (data, source, length);
+       dataLength = length;
+       numFrames = dataLength / blockAlign;
+ }
+ 
  // Destructor
  AudioSample::~AudioSample (void)
***************
*** 103,110 ****
  
  // Get a block of wave data
! // count: The number of _frames_ to get (not bytes!)
  // buffer: The buffer to store the frames in (must allocate enough)
  // Returns: the number of frames actually stored in buffer
! int AudioSample::GetData (int count, uint8_t *buffer)
  {
        int bytesCopied = 0;
--- 168,175 ----
  
  // Get a block of wave data
! // frameCount: The number of _frames_ to get (not bytes!)
  // buffer: The buffer to store the frames in (must allocate enough)
  // Returns: the number of frames actually stored in buffer
! int AudioSample::GetData (int frameCount, uint8_t *buffer)
  {
        int bytesCopied = 0;
***************
*** 118,122 ****
  
        // Number of bytes to copy is number of frames to copy * frame size
!       int bytesCount = count * blockAlign;
  
        if (type == SAMPLE_TYPE_NONE)
--- 183,187 ----
  
        // Number of bytes to copy is number of frames to copy * frame size
!       int bytesCount = frameCount * blockAlign;
  
        if (type == SAMPLE_TYPE_NONE)
***************
*** 134,138 ****
                        return -1;
                }
!               // Number of bytes to copy shouldn't take us beyond the end of 
the array
                int bytesToCopy = (position + bytesCount) > dataLength ? 
(dataLength - position) : bytesCount;
                // Read into the buffer provided the number of bytes to copy
--- 199,203 ----
                        return -1;
                }
!               // Number of bytes to copy shouldn't take us beyond the end of 
the data
                int bytesToCopy = (position + bytesCount) > dataLength ? 
(dataLength - position) : bytesCount;
                // Read into the buffer provided the number of bytes to copy
***************
*** 147,151 ****
                else if (bytesCopied < bytesToCopy)
                {
!                       printf ("Error reading wave data from file (didn't get 
enough bytes): %s\n", strerror (errno));
                        // Return what we got, driver will assume end of data 
and move to next sample in queue
                }
--- 212,216 ----
                else if (bytesCopied < bytesToCopy)
                {
!                       PLAYER_ERROR1 ("Error reading wave data from file 
(didn't get enough bytes): %s\n", strerror (errno));
                        // Return what we got, driver will assume end of data 
and move to next sample in queue
                }
***************
*** 244,248 ****
  bool AudioSample::ToPlayer (player_audio_wav_t *dest)
  {
!       if (type == SAMPLE_TYPE_NONE || data == NULL)
        {
                PLAYER_WARN ("No sample to convert to player format");
--- 309,315 ----
  bool AudioSample::ToPlayer (player_audio_wav_t *dest)
  {
! 
! 
!       if (type == SAMPLE_TYPE_NONE || (type == SAMPLE_TYPE_MEM && data == 
NULL) || (type == SAMPLE_TYPE_FILE && filePath == NULL))
        {
                PLAYER_WARN ("No sample to convert to player format");
***************
*** 294,301 ****
        }
  
!       // Copy at most PLAYER_AUDIO_WAV_BUFFER_SIZE bytes of data
!       uint32_t bytesToCopy = PLAYER_AUDIO_WAV_BUFFER_SIZE;
!       if (dataLength < bytesToCopy)
!               bytesToCopy = dataLength;
        if (type == SAMPLE_TYPE_FILE)
        {
--- 361,368 ----
        }
  
!       // Copy as many frames as can fit into PLAYER_AUDIO_WAV_BUFFER_SIZE 
bytes
!       uint32_t framesToCopy = PLAYER_AUDIO_WAV_BUFFER_SIZE / blockAlign;
!       if (numFrames < framesToCopy)
!               framesToCopy = numFrames;
        if (type == SAMPLE_TYPE_FILE)
        {
***************
*** 305,309 ****
                SetDataPosition (0);
                // Grab some data, put it in the player struct
!               GetData (bytesToCopy, dest->data);
                // Move back to where we were
                SetDataPosition (currentPos);
--- 372,376 ----
                SetDataPosition (0);
                // Grab some data, put it in the player struct
!               printf ("copied %d frames\n", GetData (framesToCopy, 
dest->data));
                // Move back to where we were
                SetDataPosition (currentPos);
***************
*** 312,318 ****
        {
                // Just copy. Nice and easy.
!               memcpy (&dest->data, data, bytesToCopy);
        }
!       dest->data_count = bytesToCopy;
  
        return true;
--- 379,385 ----
        {
                // Just copy. Nice and easy.
!               memcpy (&dest->data, data, framesToCopy * blockAlign);
        }
!       dest->data_count = framesToCopy * blockAlign;
  
        return true;
***************
*** 641,677 ****
  {
        if (type == SAMPLE_TYPE_FILE)
!               printf ("File sample, path: %s\n", filePath);
        else if (type == SAMPLE_TYPE_MEM)
!               printf ("Memory sample\n");
        else
!               printf ("Empty sample\n");
!       printf ("Num channels:\t%d\n", numChannels);
!       printf ("Sample rate:\t%d\n", sampleRate);
!       printf ("Byte rate:\t%d\n", byteRate);
!       printf ("Block align:\t%d\n", blockAlign);
!       printf ("Format:\t\t");
        switch (bitsPerSample)
        {
                case 8:
!                       printf ("Unsigned 8 bit\n");
                        break;
                case 16:
!                       printf ("Signed 16 bit little-endian\n");
                        break;
                case 24:
                        if ((blockAlign / numChannels) == 3)
!                               printf ("Signed 24 bit 3-byte little-endian\n");
                        else
!                               printf ("Signed 24 bit little-endian\n");
                        break;
                case 32:
!                       printf ("Signed 32 bit little-endian\n");
                        break;
                default:
!                       printf ("Unplayable format: %d bit\n", bitsPerSample);
        }
!       printf ("Num frames:\t%d\n", numFrames);
!       printf ("Data length:\t%d\n", dataLength);
        if (type == SAMPLE_TYPE_FILE)
!               printf ("Data starts at:\t%d\n", headerSize);
  }
--- 708,744 ----
  {
        if (type == SAMPLE_TYPE_FILE)
!               cout << "File sample, path: " << filePath << endl;
        else if (type == SAMPLE_TYPE_MEM)
!               cout << "Memory sample" << endl;
        else
!               cout << "Empty sample" << endl;
!       cout << "Num channels:\t" << numChannels << endl;
!       cout << "Sample rate:\t" << sampleRate << endl;
!       cout << "Byte rate:\t" << byteRate << endl;
!       cout << "Block align:\t" << blockAlign << endl;
!       cout << "Format:\t\t" << endl;
        switch (bitsPerSample)
        {
                case 8:
!                       cout << "Unsigned 8 bit" << endl;
                        break;
                case 16:
!                       cout << "Signed 16 bit little-endian" << endl;
                        break;
                case 24:
                        if ((blockAlign / numChannels) == 3)
!                               cout << "Signed 24 bit 3-byte little-endian" << 
endl;
                        else
!                               cout << "Signed 24 bit little-endian" << endl;
                        break;
                case 32:
!                       cout << "Signed 32 bit little-endian" << endl;
                        break;
                default:
!                       cout << "Unplayable format: " << bitsPerSample << " 
bit" << endl;
        }
!       cout << "Num frames:\t" << numFrames << endl;
!       cout << "Data length:\t" << dataLength << endl;
        if (type == SAMPLE_TYPE_FILE)
!               cout << "Frames start at:\t" << headerSize << endl;
  }

Index: alsa.h
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/audio/alsa.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** alsa.h      24 Aug 2006 00:28:14 -0000      1.6
--- alsa.h      12 Feb 2007 01:30:13 -0000      1.7
***************
*** 44,48 ****
  
  
////////////////////////////////////////////////////////////////////////////////
! // Describes an ALSA mixer element
  typedef uint32_t ElemCap;
  const ElemCap ELEMCAP_CAN_PLAYBACK            = 0x0001;
--- 44,48 ----
  
  
////////////////////////////////////////////////////////////////////////////////
! // Capabilities of a mixer element
  typedef uint32_t ElemCap;
  const ElemCap ELEMCAP_CAN_PLAYBACK            = 0x0001;
***************
*** 58,61 ****
--- 58,62 ----
  // const ElemCap ELEMCAP_CAP_JOINED_SWITCH    = 0x0400;
  
+ // Describes an ALSA mixer element
  typedef struct MixerElement
  {
***************
*** 93,107 ****
                // Driver options
                bool useQueue;                                  // If should 
use a queue for playback or just stop currently playing
                char *pbDevice;                                 // Name of the 
playback device
                char *mixerDevice;                              // Name of the 
mixer device
                char *recDevice;                                // Name of the 
record device
!               uint32_t cfgPBPeriodTime;               // Length of a playback 
period in milliseconds (configured value)
!               uint32_t cfgPBBufferTime;               // Length of the 
playback buffer in milliseconds (configured value)
                uint32_t silenceTime;                   // Length of silence to 
put between samples in the queue
!               uint32_t cfgRecBufferTime;              // Length of the record 
buffer in milliseconds (configured value)
!               uint32_t cfgRecPeriodTime;              // Length of a record 
period in milliseconds (configured value)
                uint8_t recNumChannels;                 // Number of channels 
for recording
                uint32_t recSampleRate;                 // Sample rate for 
recording
!               uint8_t recBits;                                // Sample bits 
for recording
  
                // ALSA variables
--- 94,112 ----
                // Driver options
                bool useQueue;                                  // If should 
use a queue for playback or just stop currently playing
+               uint8_t debugLevel;                             // Debug info 
level
+               char **mixerFilters;                    // Null-terminated 
array of strings to filter mixer elements by
+               bool mixerFilterExact;                  // If mixer filters 
need to match element names exactly
                char *pbDevice;                                 // Name of the 
playback device
                char *mixerDevice;                              // Name of the 
mixer device
                char *recDevice;                                // Name of the 
record device
!               uint32_t cfgPBPeriodTime;               // Length of a playback 
period in milliseconds
!               uint32_t cfgPBBufferTime;               // Length of the 
playback buffer in milliseconds
                uint32_t silenceTime;                   // Length of silence to 
put between samples in the queue
!               uint32_t cfgRecBufferTime;              // Length of the record 
buffer in milliseconds
!               uint32_t cfgRecStoreTime;               // Length of time to 
store recorded data before sending to clients
!               uint32_t cfgRecPeriodTime;              // Length of a record 
period in milliseconds
                uint8_t recNumChannels;                 // Number of channels 
for recording
                uint32_t recSampleRate;                 // Sample rate for 
recording
!               uint8_t recBits;                                // Sample bits 
per frame for recording
  
                // ALSA variables
***************
*** 127,137 ****
  
                // Other driver data
!               int nextSampleIdx;                                      // Next 
free index to store a sample at
                StoredSample *samplesHead, *samplesTail;        // Stored 
samples
                QueueItem *queueHead, *queueTail;       // Queue of audio data 
waiting to play
                PBState playState;                              // Playback 
state
                PBState recState;                               // Record state
! //            AudioSample *recData;                   // Somewhere to store 
recorded data before it goes to the client
!               player_audio_wav_t *recData;    // Somewhere to store recorded 
data before it goes to the client
  
                // Internal functions
--- 132,145 ----
  
                // Other driver data
!               int nextSampleIdx;                              // Next free 
index to store a sample at
                StoredSample *samplesHead, *samplesTail;        // Stored 
samples
                QueueItem *queueHead, *queueTail;       // Queue of audio data 
waiting to play
                PBState playState;                              // Playback 
state
                PBState recState;                               // Record state
!               uint32_t recDataLength;                 // Length of recorded 
data buffer (in bytes)
!               uint32_t recDataOffset;                 // Current end of 
recorded data in recData
!               uint8_t *recData;                               // Somewhere to 
store recorded data before it goes to the client
!               int recDest;                                    // Destination 
of recorded data: -ve for to clients via data packets,
!                                                                               
// >=0 for to stored sample at that index
  
                // Internal functions
***************
*** 163,167 ****
--- 171,177 ----
                bool SetupRecord (void);
                bool SetRecParams (void);
+               bool SetupRecordBuffer (uint32_t length);
                void RecordCallback (int numFrames);
+               void HandleRecordedData (void);
                void PublishRecordedData (void);
  
***************
*** 177,180 ****
--- 187,191 ----
                bool EnumElementCaps (MixerElement *element);
                MixerElement* SplitElements (MixerElement *elements, uint32_t 
&count);
+               MixerElement* FilterElements (MixerElement *elements, uint32_t 
&count);
                void CleanUpMixerElements (MixerElement *elements, uint32_t 
count);
                void MixerDetailsToPlayer 
(player_audio_mixer_channel_list_detail_t *dest);
***************
*** 194,197 ****
--- 205,209 ----
                int HandleSampleLoadReq (player_audio_sample_t *data, 
MessageQueue *resp_queue);
                int HandleSampleRetrieveReq (player_audio_sample_t *data, 
MessageQueue *resp_queue);
+               int HandleSampleRecordReq (player_audio_sample_rec_req_t *data, 
MessageQueue *resp_queue);
                int HandleMixerChannelListReq 
(player_audio_mixer_channel_list_detail_t *data, MessageQueue *resp_queue);
                int HandleMixerChannelLevelReq 
(player_audio_mixer_channel_list_t *data, MessageQueue *resp_queue);

Index: alsa.cc
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/audio/alsa.cc,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** alsa.cc     4 Sep 2006 11:53:56 -0000       1.7
--- alsa.cc     12 Feb 2007 01:30:13 -0000      1.8
***************
*** 31,35 ****
  
  This driver provides access to sound playing and recording functionality 
through
! the Advanced linux Sound Architecture (ALSA) system available on 2.6 series
  kernels (and before via patches/separate libraries).
  
--- 31,35 ----
  
  This driver provides access to sound playing and recording functionality 
through
! the Advanced Linux Sound Architecture (ALSA) system available on 2.6 series
  kernels (and before via patches/separate libraries).
[...1124 lines suppressed...]
        if (mixerHandle)
***************
*** 2259,2262 ****
--- 2619,2626 ----
                return HandleSampleRetrieveReq 
(reinterpret_cast<player_audio_sample_t*> (data), resp_queue);
        }
+       else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_REQ, 
PLAYER_AUDIO_SAMPLE_REC_REQ, device_addr) && recHandle)
+       {
+               return HandleSampleRecordReq 
(reinterpret_cast<player_audio_sample_rec_req_t*> (data), resp_queue);
+       }
        else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_REQ, 
PLAYER_AUDIO_MIXER_CHANNEL_LIST_REQ, device_addr) && mixerHandle)
        {
***************
*** 2268,2272 ****
        }
  
- 
        return -1;
  }
--- 2632,2635 ----

Index: audio_sample.h
===================================================================
RCS file: /cvsroot/playerstage/code/player/server/drivers/audio/audio_sample.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** audio_sample.h      16 Jul 2006 02:50:08 -0000      1.1
--- audio_sample.h      12 Feb 2007 01:30:14 -0000      1.2
***************
*** 34,37 ****
--- 34,39 ----
        public:
                AudioSample (void);
+               AudioSample (const player_audio_wav_t *source);
+               AudioSample (const uint8_t *source, uint32_t length, uint16_t 
channels, uint32_t sr, uint16_t bps);
                ~AudioSample (void);
  
***************
*** 40,44 ****
                uint32_t GetDataPosition (void) const;          // Get current 
position in the data (in frames, not bytes)
                uint32_t GetDataLength (void) const;            // Get length 
of data (in frames, not bytes)
!               int GetData (int count, uint8_t *buffer);       // Get a block 
of data
                void ClearSample (void);                                        
// Clear the entire sample (including format), making this a SAMPLE_TYPE_NONE
                bool FillSilence (uint32_t time);                       // Fill 
the sample with silence
--- 42,46 ----
                uint32_t GetDataPosition (void) const;          // Get current 
position in the data (in frames, not bytes)
                uint32_t GetDataLength (void) const;            // Get length 
of data (in frames, not bytes)
!               int GetData (int frameCount, uint8_t *buffer);  // Get a block 
of data from current position
                void ClearSample (void);                                        
// Clear the entire sample (including format), making this a SAMPLE_TYPE_NONE
                bool FillSilence (uint32_t time);                       // Fill 
the sample with silence


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to