Streaming Voice Data Over openDDS!!! PreviousNext
Data Distribution Service (DDS) Forum > DDS Technical Forum >
Message/Author
Next message jeetendra kumar  posted on Friday, June 15, 2012 - 04:02 pm
Hi,
I want to pass the audio data over openDDS, but unable to do that.
What I am doing is taking the voice data from mic using portAudio library and passing it to openDDS through publisher and in the subscriber side,in on_data_available() function, writing that data to speaker using portAudio library.

My voice data is (void*), that I want to pass it to openDDS, but in the IDL, i can't declare (void*), so I am using "string" there as declaration and typecasting in place of passing to openDDS, in write() method.

same thing, I am doing in subscriber side and reading that data(openDDS) and passing it to Reading library of portAudio library.

My problem is that when I am passing that voice data(char*) to openDDS, it's not able to do that properly, and openDDS IDL data, I am finding the value NULL same in the subscriber side while reading.

Could you please suggest, how to go in this approach where I need to pass voice data over openDDS, and data is void*. So if any snippet code, if you able to provide..then it'll be great help...

Thanks In Advance!!!

Bye,
Jeet
Next message Trevor Fields  posted on Monday, June 18, 2012 - 06:37 pm
Jeet,
Have you looked at using an octet sequence (CORBA::-OctetSeq)?

I would expect that the possible zero values would cause problems using a string.

Trevor
Next message jeetendra kumar  posted on Monday, June 18, 2012 - 08:49 pm
Thanx Trevor for reply... :-)

I tried the Corba::-OctetSeq..but main problem is coming while passing data from void* or char* to octet data.

As I am getting the data from mic as char*/void* sampleBlock, now I need to pass this data(SampleBlock) to CORBA::-OctetSeq userData.

I am just initialising the octet data in for loop using the data of sampleBlock like below:
for(ii=0;ii<strlen(sampleBlock);ii++)
message::userData[ii]=sampleBlock[ii];

and passing the octet data to Write method of openDDS in publisher side.

and same I am doing in subscriber side while reading the data from octet data,
but here also I am getting the problem of passing the octet data into char*, then I am using message.userData.getBuffer() to get the char* and pass to audio api.

But after doing all these things..I am getting just the noise from application and no voice... :-(

I think main problem coming while initialising the octet data with input data(as here sampleBlock) and then at the subscriber side again pass the octet data to char*(sampleBlock).

Could you suggest some way to pass the octet data to char* and vice-versa?

Thanx again Trevor!!!
Next message jeetendra kumar  posted on Monday, June 18, 2012 - 08:54 pm
Thanx Trevor for reply... :-)

I tried the Corba::-OctetSeq..but main problem is coming while passing data from void* or char* to octet data.

As I am getting the data from mic as char*/void* sampleBlock, now I need to pass this data(SampleBlock) to CORBA::-OctetSeq userData.

I am just initialising the octet data in for loop using the data of sampleBlock like below:
for(ii=0;ii<strlen(sampleBlock);ii++)
message::userData[ii]=sampleBlock[ii];

and passing the octet data to Write method of openDDS in publisher side.

and same I am doing in subscriber side while reading the data from octet data,
but here also I am getting the problem of passing the octet data into char*, then I am using message.userData.getBuffer() to get the char* and pass to audio api.

But after doing all these things..I am getting just the noise from application and no voice... :-(

I think main problem coming while initialising the octet data with input data(as here sampleBlock) and then at the subscriber side again pass the octet data to char*(sampleBlock).

Could you suggest some way to pass the octet data to char* and vice-versa?

Thanx again Trevor!!!
Next message Trevor Fields  posted on Tuesday, June 19, 2012 - 06:10 pm
Jeet,

Are you initializing the length of the octet sequence first (or is it a fixed length type) ?
message.userData.length(size)


Is strlen a valid way to determine the length of the sampleBlock?


Can you do some hex dumping of the data to verify that
(1) publisher side - the data put in the message.userData is the same as the data in the sampleBlock?

(2) the data received on the subscriber side is the exact same data in the original sampleBlock?

(3) subscriber side - the data put in the sampleBlock is the same as the data in the message.userData?

Trevor
Next message jeetendra kumar  posted on Thursday, June 21, 2012 - 05:51 am
Thanx Trevor for reply...

I initialised the message.userData.length as 0.

I am able to get the output same as sampleBlock and message.userData at publisher side but I think after 6 iteration of 1024 bytes, it start overflowing. Meassage used to come from "ReadStream: Input overflowed".

And in the subscriber side getting the data as underflow but from "WriteStream: Output underflowed".

And one thing to observe that without speaking to mic also, m getting some data in sampleBlock and message.userData???

Is there any workaround to resolve this overflow and underflow issue?
Next message Trevor Fields  posted on Monday, June 25, 2012 - 05:32 pm
Initialize the message.userData.length to the actual length of the data it will contain. It can be increased one spot at a time but it is very inefficient and poor performance.

I am not familiar with the sampleBlock code, so I don't know where the overflowed messages is coming from. I expect that the underflowed is a result of the missing data from the overflow.

Data may be sent even with no mic input for various reasons. The system should not have a problem sending smaller pieces of data.


It is starting to sound like the issues you are having is not with the DDS but your input source. This is not really my area and would require a fair bit of additional work. If this is a business operation you can always seek out support from Object Computing www.ociweb.com

Trevor
Next message jeetendra kumar  posted on Tuesday, June 26, 2012 - 10:16 am
Thanx Trevor,

Yep, initial I was initialising 0 and then assigning the value to message.userdata[ii]. but latter I remove initialising 0 and directly intializing with the data from sampleBlock.

While passing the audio data over openDDS, I am finding the noise, and later input overflow & output underflow. But the same functionality is working fine without DDS.

Do you think any workaround possible in DDS, where noise & overflow can be removed?

Thanx Trevor
Next message Trevor Fields  posted on Tuesday, June 26, 2012 - 05:30 pm
Jeet,

About the noise, if the data put into OpenDDS is the same as is coming out, I don't know how to explain the noise.

As for overflow, it sounds like the method used to put the data into OpenDDS is taking too long.
Have you looked into memcopy operations to try and copy the data faster?
Next message jeetendra kumar  posted on Wednesday, June 27, 2012 - 03:14 pm
Thanx Trevor...
I tried memcpy() also but no luck... :-(

Do you have any snippet of code which useses sequence<octet> to stream raw data over DDS?

I tried all means, but finding no luck in this...
Next message Hans van 't Hag  posted on Wednesday, June 27, 2012 - 03:40 pm
maybe time to try a different OpenSource DDS implementation :-) ?
Next message jeetendra kumar  posted on Thursday, June 28, 2012 - 06:38 am
Thanks Hans for alternative thought... :-)

Probably openSplice is the buzz, but not sure how much it will help me to transfer live audio data.

Any help in this will be appreciative.
Next message Hans van 't Hag  posted on Thursday, June 28, 2012 - 11:49 am
I'd say that just using an unbounded octet-sequence should do the trick to transfer random-size opaque data. Our bundled 'pingpong' example in the community-edition shows how to fill such a sequence (in the pingpong case its using an unbounded character-sequence) ..
Next message jeetendra kumar  posted on Thursday, July 26, 2012 - 03:07 pm
Hi Hans,
I used the openSplice for just passing "Hello" data from publisher to subscriber using sequence<octet>, I got the almost the data on subscriber side but little bit garbage with that in both side..I am enclosing the code below:
//HelloWorldData.idl
module HelloWorldData
{
typedef sequence<octet> seq_oct;
struct Msg {
seq_oct contents;
};
#pragma keylist Msg
};
//HelloWorldDataDcps.h
struct MsgSeq_uniq_ {};
typedef DDS_DCPSUVLSeq <msg,> MsgSeq;

//HelloWorldDataPublisher.cpp
Msg msgInstance; /* Example on Stack */
char buffer[15];

msgInstance.contents.length(15);
cout<<"maximum length of contents: "<<msgInstance.contents.maximum()<<endl;
msgInstance.contents = CORBA::string_dup("Hello");
cout<<"length of contents: "<<msgInstance.contents.length()<<endl;

cout << "=== [Publisher] writing a message containing :" << endl;
memcpy(buffer,msgInstance.contents.get_buffer(),msgInstance.contents.length());
cout << " Message : \"" << buffer << "\"" << endl;

ReturnCode_t status = HelloWorldWriter->write(msgInstance, NULL);

//HelloWorldDataSubscriber.cpp
MsgSeq msgList;
SampleInfoSeq infoSeq;
status = HelloWorldReader->take(msgList, infoSeq, LENGTH_UNLIMITED,
ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);

checkStatus(status, "msgDataReader::take");
for (CORBA::ULong j = 0; j < msgList.length(); j++)
{
cout << "=== [Subscriber] message received :" << endl;
cout << " Message : \"" << msgList[j].contents.get_buffer() << "\"" << endl;
closed = true;
}
memcpy(buffer,msgList.get_buffer(),11);//copy the octet data to buffer(char*)
cout<<"buffer->"<<buffer<<endl;

status = HelloWorldReader->return_loan(msgList, infoSeq);


I am getting the output in publisher as:
HelloWorldDataPublisher.exe
maximum length of contents: 15
length of contents: 5
=== [Publisher] writing a message containing :
Message : "HellodA"

and in subscriber side:
HelloWorldDataSubscriber.exe
=== [Subscriber] Ready ...
=== [Subscriber] message received :
Message : "Hello©÷©÷©÷©÷"
buffer->¢À

I am not able to fix why in the publisher side it's not coming as correct, and in subscriber side both octet data and when it passed to buffer(char*) then it's giving garbage data.

Could you suggest how to fix the above issue, by avoiding the garbage on both pub and sub?

Looking forward for your suggestion and help.

Bye,
Jeetendra
Next message jeetendra kumar  posted on Friday, July 27, 2012 - 02:32 pm
Any luck, Hans ... :-)
Next message jeetendra kumar  posted on Friday, July 27, 2012 - 03:28 pm
Hi Hans,
I am able to remove the garbage value from publisher side, by just increasing the buffer length by 1 more. But still not able to remove the garbage data from subscriber side. :-(

Is there any way that get_buffer() function used in subscriber side, only return the number of data we require. Basically, I want to restrict it only the known number of data it should return(because f garbage data it returing with the original sent data). Below is the code which used to retrieve data from msgList:
msgList[j].contents.get_buffer()

Any help in this will be appreciated!!!

Bye,
Jeetendra
Back to top
Add Your Message Here
Post:
Username: Posting Information:
This is a private posting area. Only registered users and moderators may post messages here.
Password:
Options: Post as "Anonymous"
Enable HTML code in message
Automatically activate URLs in message
Action: