I have written samples from microphone input into a Float32 array, and now I want to turn that array of samples into a WAV file.
Apparently a good way to do it is to use a utility class from the DIRAC library, as its EAFWrite class has a writeFloats method that should do the trick.
When I call the EAFWrite's writeFloats method I get a "Cannot convert 'float' to float**" error. Here's the call:
[mWriter writeFloats:128 fromArray:mySession];
The array was initialised thus:
Float32 mySession[10000000] = {0};
What do you think is wrong? Is this a problem about pointers?
A peek at the writeFloats:fromArray: source code (it's included in the library, doncha kno) reveals that the data parameter should actually be an array of array pointers, with one array pointer per channel. Presumably you specified one channel in some previous message to mWriter, so now you can just do this:
Float32 *channelsData[1] = { mySession };
[mWriter writeFloats:128 fromArray:channelsData];
or if you want to get really tricky:
[mWriter writeFloats:128 fromArray:(Float32 *[]){ mySession }];
Related
I have a class with a struct property called myStruct:
properties
myStruct;
end
I would like to save the struct to a .mat file. I tried:
save -append registers.mat myStruct;
But it gives the error:
Variable 'myStruct' not found.
I have different functions for updating the struct, like:
function configureChannel( obj, Channel )
myStruct.Channel = Channel;
save -append registers.mat myStruct;
end
function updateConfiguration( obj, dataPath )
myStruct.EN = 1;
save -append registers.mat myStruct;
end
These are all functions of the same class.
I think that the main problem in this code is how you access myStruct from your functions. Take a look at the following piece of code:
function configureChannel( obj, Channel )
myStruct.Channel = Channel;
...
end
What you intended for it to do was to assign Channel into the Channel field of the current object's myStruct's Channel property. What it actually does is equivalent to calling:
myStruct = struct('Channel', Channel);
That is, you create a new local variable in the current workspace/scope of configureChannel, without actually updating the property of the object, obj.
So the first correction you need to make is how you access myStruct in your setter:
obj.myStruct.Channel = Channel;
Next is the issue of saving.
When dumping a copy of an object's field to a file, I would expect save to treat your arbitrary object as a struct, and so struct saving conventions should apply:
'-struct',structName | Store the fields of the scalar structure specified by structName as individual variables in the file. For example, save('filename.mat','-struct','S') saves the scalar structure, S.
Thus, I would expect the following to work disclaimer: I didn't test it:
save('filename.mat','-struct','obj.myStruct');
Other alternatives in case the above fails:
save('filename.mat','obj.myStruct'); % Alternative #1
tmp = obj.myStruct; save('filename.mat','tmp'); % Alternative #2
One last thing - as you may have noticed, I'm using the function form of save, because I consider it to be more maintainable/readable/fool-proof:
save(filename,variables,'-append');
I have a ListBox in a Windows app that lists the people in a chat session. This is defined as follows:
Win32::API::Struct->typedef('UserItem', qw {
USHORT uid;
TCHAR realName[256];
TCHAR aliasName[256];
}
) or die "Typedef error $! \n";
my $user_data = Win32::API::Struct->new('UserItem');
Now I want to send a LB_GETITEMDATA message to the window to the get the attendee item details defined by the struct.
Using Win32::API, I do this:
my $LB_GETITEMDATA = 0x0199;
my $SendMessage = Win32::API->new("user32", "SendMessage", "NNNN", "S");
... # Here is the code to find the window handle, which is $hwnd.
$user_data = $SendMessage->Call($hwnd, $LB_GETITEMDATA, 0, 0); # Get the first item.
Now, I'd think $user_data struct will contain the first item's details, but it is actually undef & I don't get any LB_ERR either. What am I doing wrong?
That makes no senses to me. How can Win32::API know what kind of struct is being returned by SendMessage if you don't tell it? It can't possibly create the right type of object from the information you provided it.
I see nothing on how to use "S" for the return value. I think you might have to use the prototype interface if you want to return value to be unpacked into a ::Struct object. That's the only one documented.
But before you start messing with that, change the return type to "N" and see if you get a pointer back. If you get zero, it could be a problem with the listbox or with the arguments (particularly, the handle or the message number, since "NNNN" looks right to me), and you should fix that first. Then you can worry about the return value if it's still a problem.
If it is a problem with getting ::Struct to work, you could always unpack the
structure yourself.
# Use "N" for return.
my ($uid, $realName, $aliasName) =
unpack('S Z256 Z256', # Unpack fields of structure.
unpack('P514', pack('J', $rv))); # Get bytes of the structure.
You have to set the item data with LB_SETITEMDATA after adding the string. The data is just a pointer sized value so each $user_data struct has to exist in memory as long as the item exists in the list...
I have an instance variable which is a struct, for example:
struct Data {
UInt32 i;
UInt32 arr[1];
};
And a property is defined in my class:
#property struct Data data; // and the corresponding #synthesize in the imp file
Now, I am aware that changing the values of i and arr through the getter of data is conceptually wrong, since I will be accessing the copy of data returned by the getter (the correct way is accessing it using self->data).
However some general Objective-C questions arise regarding the following lines:
self.data.i = 1; // produces compile error
self.data.arr[0] = 1; // compiles ok
First, why does the first line produces a compile error, and the 2nd line does not?
Second, if the dot syntax in the above line (self.data) is just a syntactic sugar to [self data], why do I get 2 different (although similar) compile errors?
self.data.i = 1; // error: Expression is not assignable
[self data].i = 1; // error: Semantic Issue: Assigning to 'readonly' return result of an objective-c message not allowed
Actually, structs are passed by value in C (and Objective C). That means that your property actually returns a read only copy (rvalue) of the internal "Data" type. The assignment is to the temporary returned copy, which the compiler (rightfully) flags as a bit suspect.
The second line that compiles correctly does so since self.data.arr returns a read only UInt32*, but when you index it with [0] and write to that, you're not writing to the pointer, you're writing to the memory that it points to which is allowed.
Hi I am trying to init an object with a double value in the format double filter[3][3];
but i keep getting the following error.
cannot convert 'double[3][3]' to 'double' in assignment.
in my header i have this
#interface filter : NSObject
{
double **matrix;
}
#property(nonatomic)double **matrix;
-(id)initWithMatrix:(double**)filterMatrix;
inside my class i have this method.
-(id)initWithMatrix:(double**)filterMatrix
{
matrix = filterMatrix;
return self;
}
and i am trying to call it like this.
double filter[3][3] = {0,0,0,0,1,0,0,0,0};
MyMatrix *myMatrix = [[MyMatrix alloc] initWithMatrix:filter];
I now get the error.
Error: Cannot convert double[*][3] to double** in argument passing
Any help on this issue would be amazing.
Thanks
A
That's because double** isn't the equivalent of double[*][*]. In fact, double[*][*] is an invalid type, because it leaves the stride undefined. double** is a pointer to a pointer to a double, or to put it another way, it's a pointer to an array of doubles. You should just use double* as your type.
Edit: To clarify, double[*][3] is still just an array of doubles, even though it has 2 dimensions. This is still the equivalent of double*.
A two-dimensional array is not the same thing as a pointer-to-a-pointer. You have two choices - change the filter class to contain a 2D array, or change your initialization to use pointer-to-pointers.
In choice #1, you're could keep a copy of the array in your filter instance, instead of just holding a pointer. You need to change the class interface:
#interface filter : NSObject
{
double matrix[3][3];
}
-(id)initWithMatrix:(double[3][3])filterMatrix;
Then your implementation of initWithMatrix: can just do a memcpy() or the equivalent to copy the data into your instance.
Choice #2 is a bit different. Keep your other code the way it is, but change your initialization of filter:
double row0[3] = {0,0,0};
double row1[3] = {0,1,0};
double row2[3] = {0,0,0};
double **filter[3] = { row0, row1, row2 };
It's probably safer to malloc() all of those arrays, since otherwise you're going to end up with references to stack variables in your filter class, but I think you get the idea.
you are passing as a parameter a double 2d array(double[][]) when your method signature asks for a double (a primitive like 34.2).
set the method declaration to
- (id)initWithMatrix:(double*) matrix;
this passes a pointer to your array (2d) to the method.
edit: missed a semicolon.
Hi I am trying to init an object with a double value in the format double filter[3][3];
but i keep getting the following error.
cannot convert 'double[3][3]' to 'double' in assignment.
in my header i have this
#interface filter : NSObject
{
double **matrix;
}
#property(nonatomic)double **matrix;
-(id)initWithMatrix:(double**)filterMatrix;
inside my class i have this method.
-(id)initWithMatrix:(double**)filterMatrix
{
matrix = filterMatrix;
return self;
}
and i am trying to call it like this.
double filter[3][3] = {0,0,0,0,1,0,0,0,0};
MyMatrix *myMatrix = [[MyMatrix alloc] initWithMatrix:filter];
I now get the error.
Error: Cannot convert double[*][3] to double** in argument passing
Any help on this issue would be amazing.
Thanks
A
That's because double** isn't the equivalent of double[*][*]. In fact, double[*][*] is an invalid type, because it leaves the stride undefined. double** is a pointer to a pointer to a double, or to put it another way, it's a pointer to an array of doubles. You should just use double* as your type.
Edit: To clarify, double[*][3] is still just an array of doubles, even though it has 2 dimensions. This is still the equivalent of double*.
A two-dimensional array is not the same thing as a pointer-to-a-pointer. You have two choices - change the filter class to contain a 2D array, or change your initialization to use pointer-to-pointers.
In choice #1, you're could keep a copy of the array in your filter instance, instead of just holding a pointer. You need to change the class interface:
#interface filter : NSObject
{
double matrix[3][3];
}
-(id)initWithMatrix:(double[3][3])filterMatrix;
Then your implementation of initWithMatrix: can just do a memcpy() or the equivalent to copy the data into your instance.
Choice #2 is a bit different. Keep your other code the way it is, but change your initialization of filter:
double row0[3] = {0,0,0};
double row1[3] = {0,1,0};
double row2[3] = {0,0,0};
double **filter[3] = { row0, row1, row2 };
It's probably safer to malloc() all of those arrays, since otherwise you're going to end up with references to stack variables in your filter class, but I think you get the idea.
you are passing as a parameter a double 2d array(double[][]) when your method signature asks for a double (a primitive like 34.2).
set the method declaration to
- (id)initWithMatrix:(double*) matrix;
this passes a pointer to your array (2d) to the method.
edit: missed a semicolon.