problems playing audio with mciSendString
Hello all, I would really appreciate some assistance on this. The intent is to create a vocabulary/flashcard program with proper pronunciations. Pronunciations are saved as individual mp3 files which I want to play whenever a new term is displayed. My current attempt is simply to get the the file (any mp3 file really) to play. All indication form the two references I'm using (http://msdn.microsoft.com/en- us/library/dd757161(v=VS.85).aspx and http://www.apitalk.com/windows-Programming/Play-Mp3,-Wav,-Wmv,-Mpg,- Avi-Etc-Files-In-Win32-Api-Program.html) say that this little script is supposed to work. The error codes as reported by mciSendString even suggest that it is working, however I'm not hearing any sound at all. suggestions anyone? import std.stdio : writeln; import std.string : cstring = toStringz; import std.c.windows.windows; pragma(lib, winmm.lib ); extern(Windows) { uint mciSendStringA( LPCTSTR lpszCommand, LPTSTR lpszReturnString, uint cchReturn, HANDLE hwndCallback); } uint mciSendString(string s) { return mciSendStringA( cstring(s), cast(LPTSTR)null, 0, cast(HANDLE)0 ); } void main() { auto exist = mciSendString(open CC_10_mins.mp3 type mpegvideo alias myFile); auto succeeded = mciSendString(play myFile); auto closed = mciSendString(close myFile); writeln( exist, - , succeeded, - , closed ); } PROGRAM OUTPUT == when file exists: D:\codeplay 0 - 0 - 0 when file does not exist: D:\codeplay 275 - 263 - 263
readf
Hello. I'm new to D and I stumbled upon something strange about readf while writing some test code. The code: import std.stream; import std.stdio; int main(char[][] args) { string input = 2abc; auto memstream = new TArrayStream!(string)(input); int x; memstream.readf(%d, x); char[] s = memstream.readString(x); writefln(%d:%s, x, s); // expected 2:ab, writes 2:bc. return 0; } After looking in stream.d I can understand why it is working in unexpected way (readf uses ungetc() which has no effect on readString() ), but is it intended behavior? I see in documentation that ungetc() affects only what is read afterwards with getc(), but no mention that readf() is incompatible with other reading methods. It wouldn't even be the problem if I knew for sure that there is always _exactly_ one char offset, or that return value of readf must be number of bytes read from stream. Is it so or is it all just the way it happened to be in current implementation? On another topic. Compiled with D 2.050 it won't work at all, printing object.Error: Access Violation. Apparently readf in 2.0 requires mutable string as a format string. Writing it like this memstream.readf(%d.dup, x); works. Is it intended too? On yet another topic :) Is there alternative to stream.readf? Somehow while searching for explanation of unexpected behavior I got the idea that readf and streams considered to be second-class citizens in world of D and they are not a proper way to do things, so no one really cares about them... Therefore the question. What do I use to read numbers from file?
Re: couple of really noob questions (ranges, toString)
On Mon, 1 Nov 2010 20:40:30 -0700 Jonathan M Davis jmdavisp...@gmx.com wrote: The term pop does _not_ mean that an element is returned but that it is removed from the range. This is true for pretty much anything that uses a pop function in any language - stacks, lists, etc. It _is_ true that many implementations choose to have pop return the element which is popped, but that's an implementation detail. The term pop merely indicates that an element is removed from an end of a range or container. All right, that's where I went wrong. Thank you for the clear explanation. (Now, I will continue with the article by Andrei Alexandrescu, 10 pages left :-) [But I do not know of any pop not returning the removed value in any lang or library; instead, pop is the favorite example of people arguing against the distinction between actual functions (result, but no effect) and actions (effect, but no result): naughty pop does both. Maybe call it here remove()? Even if pop's sense was defined by an all-mighty authority, we could hardly avoid people having different expectations born from previous experience, esp when it's so widespread: the two pop examples at http://en.wikipedia.org/wiki/Stack_%28data_structure%29 return the element.] I would also find current() much clearer than front(), since from the client's perspective it looks like shrinking the collection (or view) instead of traversing it; see the confusion expressed by the OP's original question; but well... Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: subclassing
I'll come back with a more complete answer latter, but first. spir Wrote: * I wrote Range as class, but I rather meant an interface. D does not let me do that, apparently because there is no data slot in a D interface. Is then an interface a kind of data-less superclass? Or is there something I misunderstand? Interfaces describe what can something of that type can do, not what it has. Data fields are not allowed only function signatures and functions that perform local modifications. auto range = ...; while (range.continues) { doSomethingWith(range.element); range.step(); } Note that you are not actually using a Range as it is defined by D. In fact it is exactly the same, but named differently, here is what D's range interface looks like. auto range = ...; while (!range.empty) { doSomethingWith(range.front); range.popFront(); }
Re: exceptions thrown by new / object constructor ?
Jesse Phillips wrote: I thought there was a Bug report on this, but I guess not. I say report it. Ether it should compile or the compiler should error that a constructor can not be nothrow. This has already been fixed in svn, and will be in the next release. See bug 3020. nothrow is painful and limited in 2.050, but should be quite usable in 2.051.
Re: subclassing
On Tue, 02 Nov 2010 10:39:27 -0400 Jesse Phillips jessekphillip...@gmail.com wrote: I'll come back with a more complete answer latter, but first. spir Wrote: * I wrote Range as class, but I rather meant an interface. D does not let me do that, apparently because there is no data slot in a D interface. Is then an interface a kind of data-less superclass? Or is there something I misunderstand? Interfaces describe what can something of that type can do, not what it has. Data fields are not allowed only function signatures and functions that perform local modifications. Thank you for the clarification. auto range = ...; while (range.continues) { doSomethingWith(range.element); range.step(); } Note that you are not actually using a Range as it is defined by D. Yes, that's precisely what I meant with experimenting around this notion [of range]. Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: subclassing
spir Wrote: * Why does D allow me redefining (data) slots in the subclass OddSquares, which exist in the superclass? (I did this first without noting, by copy paste ;-) This is either a bug or so that you don't have name clashes with all the super classes (could really reduce the available names). * There is a bug in function find -- see DEBUG lines in this func and in main. For any reason, the passed range loses its data (.element==0). If I change find's interface to take a range of type OddSquares, then all runs fine. I don't know what more to do to find the bug... Nope, the bug is because you redefined element and so Range.element is not being assigned. Remove your duplicate declarations from OddSquares and it works. I am also not sure why you have alias T type. T is already an alias for the type, and you never use it so maybe it is just having fun testing out alias. PS: I like very much this interface for input ranges :-) Decided to make output data plain state (slots T element bool continues); only step() is a method. I know this is not true OO for some conception of OO, but it is ok for me. This doesn't go against OOP in the least. The specification for a Range doesn't prevent the design you have choosen. The benefit to using functions is to calculate values instead of storing the state. I understand you are trying to discover the benefits through your own design, but D Ranges would look something like this. class OddSquares(T) { // internal state private T number ; private T max ; // methods @property bool empty() { if (this.number this.max) return true; return false; } @property int front() { return this.number * this.number ; } void popFront() { this.number += 2 ; } this(T min, T max) { // set initial internal state if (min%2 == 1) this.number = min ; else this.number = min+1 ; this.max = max ; } } I also like in this design the fact that the constructor sets the range's initial state -- or is supposed to -- so that we can use the range at once, without calling step() once to initialise it. Ah, but you do call step at the very end of the constructor. This prevents it from entering user code and is generally all that matters. You will notice I acutally removed that call for the range above. I guess you could say that the real complaint was due to the desire to time how long it took to load the data (build the ranges) and how long it took to do the filtering. That meant I was separating the initialization phase from the construction of the range itself. Any way you rarely see this creep into user code. So the only other piece to inform you of (to help you learn D) is that find is found in std.algorithm and does exactly what you have demonstrated, with a slightly different call: auto element = find!((int e){return (e200 e250))(range); or auto element = find!(a200 a250)(range); And will return a range starting at the element found, however it will not stop when over 250. For that you use filter instead. auto element = filter!(a200 a250)(range);
Re: couple of really noob questions (ranges, toString)
On Tuesday, November 02, 2010 04:16:58 spir wrote: On Mon, 1 Nov 2010 20:40:30 -0700 Jonathan M Davis jmdavisp...@gmx.com wrote: The term pop does _not_ mean that an element is returned but that it is removed from the range. This is true for pretty much anything that uses a pop function in any language - stacks, lists, etc. It _is_ true that many implementations choose to have pop return the element which is popped, but that's an implementation detail. The term pop merely indicates that an element is removed from an end of a range or container. All right, that's where I went wrong. Thank you for the clear explanation. (Now, I will continue with the article by Andrei Alexandrescu, 10 pages left :-) [But I do not know of any pop not returning the removed value in any lang or library; instead, pop is the favorite example of people arguing against the distinction between actual functions (result, but no effect) and actions (effect, but no result): naughty pop does both. Maybe call it here remove()? Even if pop's sense was defined by an all-mighty authority, we could hardly avoid people having different expectations born from previous experience, esp when it's so widespread: the two pop examples at http://en.wikipedia.org/wiki/Stack_%28data_structure%29 return the element.] C++'s pop functions don't return anything either, but it is true that many libraries in many languages choose to have pop functions return the value which is being popped. Having popFront() return a value in addition to having front look at the first value in the range wouldn't necessarily be a problem, but it isn't strictly speaking necessary. In some languages (certainly C++, though I'm not sure about D), returning a value which isn't used can mean a wasted copy or object construction which can be inefficient (particularly when dealing with large objects on the stack). Whether a pop function returns anything tends to depend on how much an efficiency concern the library writer thinks that it is and how likely they think that it is that the popped value is going to be wanted. If it's expected that someone will always want the popped value, then it can be quite nice to have the pop function return it, but if there's a good chance that they won't, then it could be an unwanted inefficiency. It all depends on the goals and concerns of the library writer. In this case, D chose to not have popFront() return anything. I would also find current() much clearer than front(), since from the client's perspective it looks like shrinking the collection (or view) instead of traversing it; see the confusion expressed by the OP's original question; but well... Except that unlike an iterator (which indicates a single element), a range indicates a range of elements, so it can have both a front and a back (similar to having two iterators indicate a range of elements), so current() would be highly confusing once you went beyond input or forward ranges. For instance, bi- directional ranges have back and popBack(), and random-access ranges have the subscript/slicing operator which can access an element or range of elements in the range, so current() would become highly confusing. What you have is a range of elements which has a clear first element (and assuming it isn't infinite or of indefinite length) a clear last element. So, front and back access them and popFront() and popBack() pop them. It is indeed generally a view of a collection of elements, but there is a definite order to them, whereas current() does not indicate order. - Jonathan M Davis
Re: subclassing
On Tuesday, November 02, 2010 09:33:16 Jesse Phillips wrote: spir Wrote: * Why does D allow me redefining (data) slots in the subclass OddSquares, which exist in the superclass? (I did this first without noting, by copy paste ;-) This is either a bug or so that you don't have name clashes with all the super classes (could really reduce the available names). * There is a bug in function find -- see DEBUG lines in this func and in main. For any reason, the passed range loses its data (.element==0). If I change find's interface to take a range of type OddSquares, then all runs fine. I don't know what more to do to find the bug... Nope, the bug is because you redefined element and so Range.element is not being assigned. Remove your duplicate declarations from OddSquares and it works. I am also not sure why you have alias T type. T is already an alias for the type, and you never use it so maybe it is just having fun testing out alias. PS: I like very much this interface for input ranges :-) Decided to make output data plain state (slots T element bool continues); only step() is a method. I know this is not true OO for some conception of OO, but it is ok for me. This doesn't go against OOP in the least. The specification for a Range doesn't prevent the design you have choosen. The benefit to using functions is to calculate values instead of storing the state. I understand you are trying to discover the benefits through your own design, but D Ranges would look something like this. class OddSquares(T) { // internal state private T number ; private T max ; // methods @property bool empty() { if (this.number this.max) return true; return false; } @property int front() { return this.number * this.number ; } void popFront() { this.number += 2 ; } this(T min, T max) { // set initial internal state if (min%2 == 1) this.number = min ; else this.number = min+1 ; this.max = max ; } } I should point out that you forgot the save property, which is required for forward ranges (though not input ranges). Without it, any algorithm which processes the range will consume it. Also, (though the OP did use a class, so I assume that's why you did), ranges are usually done with structs which makes passing them around less of an issue since structs are value types while classes are reference types. There are several range definitions in Phobos - particularly in std.range, std.algorithm, and std.container if the OP wants to look at existing ones. And since ranges are heavily used in Phobos and they have to have a very specific set of functions to work with functions in Phobos, it would be a good idea for the OP to stick to the function names that Phobos uses (as you demonstrated) or code isn't going to work with Phobos' facilities, which makes ranges a lot less useful. Ranges are for a lot more than just iterating, after all. - Jonathan M Davis
Another shared bug?
I did some experiments using shared and I came across this problem: - struct Test { void test() {} shared void test2() { (cast(Test)this).test(); } void opCall() {} } void main() { shared Test t; t.test2(); } - DMD output: test3.d(7): Error: function test3.Test.opCall () is not callable using argument types (shared(Test)) shared test3.d(7): Error: expected 0 arguments, not 1 for non-variadic function type void() test3.d(7): Error: no property 'test' for type 'void' Why does dmd think I want to call the opCall in line 7? Is this yet another bug introduced by the old property behavior? -- Johannes Pfau
read-only access
Hello, Is the D way to make read-only symbols (of a class, struct, module) to write a getter for a private symbols? Additional question: just realised one can omit () on func calls! Is this systematic when a func has no param? I thought it was not the case, because it does not work with writeln (the first func on which I tried, indeed!). Is it only because writeln is parameterized (with (T...)) or is there any other reason I'm not aware of? struct P { private int my_i; int i() {return this.my_i;} void doit() {writeln(...doing...);} } void main () { auto p = P(1); writeln(p.i: ,p.i); p.doit; } Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: read-only access
spir Wrote: Hello, Is the D way to make read-only symbols (of a class, struct, module) to write a getter for a private symbols? Yes, though it isn't like the getValue() from java. @property int i() {return this.my_i;} Additional question: just realised one can omit () on func calls! Is this systematic when a func has no param? I thought it was not the case, because it does not work with writeln (the first func on which I tried, indeed!). Is it only because writeln is parameterized (with (T...)) or is there any other reason I'm not aware of? Calling functions without () is a legacy feature left over which is how D use to do properties. Some will say this is going to be removed, but do not recall this ever being said (only that it was implied it would happen if properties were used). Personally if it doesn't go away I see no reason to have @property, as the only reason I thought it was a good idea was for when you were taking the address of a function who returns a function (makes it a little hard to read). Otherwise I like the omit-able (). writeln is a template, so I suppose you can't call it this way since it can't instantiate an instance until it knows what parameters are past. You probably could call it like this writeln!() but that kind of defeats the idea of leaving off the ().
Re: subclassing
Jonathan M Davis Wrote: I should point out that you forgot the save property, which is required for forward ranges (though not input ranges). Without it, any algorithm which processes the range will consume it. Trying to ease this guy into ranges. I did notice though, the InputRange interface requires quite a few more methods than is required for an InputRange. Specifically, moveFront and opApply. So I guess my question ends up being, why (not to you specifically...)?
Re: read-only access
On Tue, 02 Nov 2010 15:54:13 -0400, Jesse Phillips jessekphillip...@gmail.com wrote: Calling functions without () is a legacy feature left over which is how D use to do properties. Some will say this is going to be removed, but do not recall this ever being said (only that it was implied it would happen if properties were used). TDPL states it will be required. -Steve
Re: read-only access
Steven Schveighoffer Wrote: On Tue, 02 Nov 2010 15:54:13 -0400, Jesse Phillips jessekphillip...@gmail.com wrote: Calling functions without () is a legacy feature left over which is how D use to do properties. Some will say this is going to be removed, but do not recall this ever being said (only that it was implied it would happen if properties were used). TDPL states it will be required. -Steve I do not believe it does. I don't recall seeing it, nor do I think it makes any sense to even mention it considering it shouldn't mention bugs in the implementation. That said, I don't recall it mentioning functions being callable without parens.
Re: read-only access
On Tue, 02 Nov 2010 16:52:38 -0400, Jesse Phillips jessekphillip...@gmail.com wrote: Steven Schveighoffer Wrote: On Tue, 02 Nov 2010 15:54:13 -0400, Jesse Phillips jessekphillip...@gmail.com wrote: Calling functions without () is a legacy feature left over which is how D use to do properties. Some will say this is going to be removed, but do not recall this ever being said (only that it was implied it would happen if properties were used). TDPL states it will be required. -Steve I do not believe it does. I don't recall seeing it, nor do I think it makes any sense to even mention it considering it shouldn't mention bugs in the implementation. That said, I don't recall it mentioning functions being callable without parens. It does not say that functions should be callable without parentheses, because that mis-feature is deprecated. Essentially, to someone who is new to D, there is no need to mention the historical features of D. It does say that you need to put @property on functions to make them into properties. At least the copy I reviewed said that (I don't have a final copy). -Steve
Re: exceptions thrown by new / object constructor ?
On Tue, 02 Nov 2010 15:58:51 +0100, Don wrote: Jesse Phillips wrote: I thought there was a Bug report on this, but I guess not. I say report it. Ether it should compile or the compiler should error that a constructor can not be nothrow. This has already been fixed in svn, and will be in the next release. See bug 3020. nothrow is painful and limited in 2.050, but should be quite usable in 2.051. Great! Many thanks! This issue has greatly limited nothrow usage because 'new' is so common.
Re: read-only access
On Tuesday, November 02, 2010 14:14:22 spir wrote: On Tue, 2 Nov 2010 12:47:21 -0700 Jonathan M Davis jmdavisp...@gmx.com wrote: If they don't have the property attribute, then they won't work without parens (and in fact, you won't be able to use parens with them). That is how it's outlined in TPDL (The D Programming Language by Andrei Alexandrescu). However, dmd has not reached that point. It will still allow property functions to be used with parens and non-property functions to be used as property functions as long as they're void and take one parameter or return a value and take no parameters. So, once dmd is up-to-date with regards to TDPL, you'll no longer be able to use arbitrary functions as properties, but for the moment, you can. I'm not sure I like it, that properties have distinct syntax -- unless there's really distinct meaning/semantics I don't know yet. The idea is that a property is like a public member variable except that it's a function underneath the hood. So, you can write code as if it were a public member variable and yet it's value could be calculated instead of actually having a corresponding variable in the object, or it could have extra code verifying that the value you're setting it to is valid. A definite benefit of it is that you can have a public member variable and then later make it a property (because it becomes a calculated value, or you need extra code checking it's value, or whatever) without having to change all of the code where it's used. The abstraction is somewhat leaking because you can't take the address of a property function in the same way you can with a public member variable, and thing like += don't work because it's two different function calls instead of acting directly on the variable, but it can be quite useful. Other languages such as C# and Delphi have the same feature (though they have different syntax for indicating when a function is a property). It makes sense for the programmer to want to indicate when a function (generally when it represents a getter or setter) rather than have _all_ functions with a certain signature becoming properties automatically (which is what has happened in D historically). Otherwise, functions which don't really represent properties are used as if they did, and there's no consistency (except perhaps by convention) as to whether parens are used when calling functions which could be property functions. @property was the syntax chosen to indicate that a function is intended to be used as a property. It's just that dmd doesn't entirely match TDPL yet (TDPL only having come out a few months ago and Walter having been busy on stuff like 64-bit support), so functions can still be called as if they were properties even though they're not. - Jonathan M Davis
Re: problems playing audio with mciSendString
Thanks, The problem was that mciSendString was immediately returning control to the caller after being called. This simple change fixed the problem: mciSendString(play myFile wait);
Re: How would I optimize this parser?
T.D.Spense: public TagNode(String name){ this.name = name; this.children = new ArrayListNode(1); } public TagNode(String name, Node... children){ this.children = Arrays.asList(children); for (Node child : children) { child.parent = this; } } It's allowed in Java, but I can see why this can be prohibited. Java code, prints 12: class Node {} class Main { public void foo(String name) { System.out.print(1); } public void foo(String name, Node... nodes) { System.out.print(2); } public static void main(String[] args) { Main m = new Main(); m.foo(hello); m.foo(hello, new Node()); } } In D the T[]... syntax means zero or more T, so if you supply zero T, the compiler can't know what of the two methods you are calling, so it's statically forbidden. This prints 22 in Java: class Node {} class Main { public void foo(String name, Node... nodes) { System.out.print(2); } public static void main(String[] args) { Main m = new Main(); m.foo(hello); m.foo(hello, new Node()); } } Here I prefer how D is designed, it looks tidier (often it's the opposite, the C# looks designed in a more clear way compared to D). You're right about unit tests. One thing that surprised me is that unit tests are run when the program is run. For some reason I thought they were run immediately after the compilation with the appropriate flag. If you compile your code with: dmd foo.d And then you run the program: foo.exe or: ./foo Your unit tests aren't run. If you instead compile with this: dmd -unittest foo.d And then you run the program, the unittests are run and then the program is run. In D2 with a version(unittest) you may disable the running as you like. Interesting. I didn't think about GC, because there aren't any objects that get unreferenced. But, of course, garbage collector can't know about that until it runs. Right, the program builds the data structure and then now and then the GC transversed it all and marks all objects as reachable. This takes a lot of time. (Well, unless there is a mechanism for marking objects as non-collectible manually.) A simple way to make objects not collectable is to allocate them from the C heap (there is a kind of placement new in D). Tangent question. Is there a way to disable GC per application thread? I am not expert on this, I think there is no way yet. Maybe it will be added. Bye, bearophile