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