I'm building a drum machine to learn how to use MIDIs on iOS. I managed to get it working to one point, however, I have the following problem. When the user taps a certain button I need to add a sound to my MIDI loop while the MIDI player is playing and unfortunately I can't simply do:
MusicTrackNewMIDINoteEvent(track, 0, &message);
although the track is looping and has a determined length, so theoretically it should come back to 0 at one point. I also tried this:
MusicTrackNewMIDINoteEvent(track, noteTimestamp, &message);
where noteTimestamp is the timestamp I receive from the player. Finally, I managed to get it working with something like this:
MusicTrackNewMIDINoteEvent(track, noteTimestamp+.5, &message);
but it's needless to say that the .5 delay is not really what I would want for my drum machine, which should be as responsive as possible.
So, how does one tackle this problem? How can you push a note on the track as soon as possible, without any delay?
You're laying down an event on the track, and by the time you lay the event down the "playhead" is already past the point where it can do anything with it.
So continue to do what you're doing (without shifting the time) as a means to "record" the event for the next time the loop "comes around", but you'll need to fire off a midi message manually -- apart from the track as:
(int) note = 60;
(int) velocuty = 127;
(int) offset = 0;
MusicDeviceMIDIEvent(_yourSamplerUnit, kMIDIMessage_NoteOn << 4 | 0, note, velocity, offset);
Again, firing a manual midi event will allow the listener to hear the sound, and laying down the event into the track will allow your track to "record" it for the next time 'round.
Related
i read about flink`s window assigners over here: https://ci.apache.org/projects/flink/flink-docs-stable/dev/stream/operators/windows.html#window-assigners , but i cant find any solution for my problem.
as part of my project i need a windowing that the timer will start given the first element of the key and will be closed and set ready for processing after X minutes. for example:
first keyA comes at (hh:mm:ss) 00:00:02, i want all keyA will be windowing until 00:01:02, and then the timer of 1 minutes will start again only when keyA will be given as input.
Is it possible to do something like that in flink? is there a workaround?
hope i made it clear enough.
Implementing keyed windows that are aligned with the first event, rather than with the epoch, is quite difficult, in general, which I believe is why this isn't supported by Flink's window API. The problem is that with an out-of-order stream using event time processing, as earlier events arrive you may need to revise your notion of when the window began, and when it should end. For example, if the first keyA arrives at 00:00:02, but then some time later an event with keyA arrives with a timestamp of 00:00:01, now suddenly the window should end at 00:01:01, rather than 00:01:02. And if the out-of-orderness is large compared to the window length, handling this becomes quite complex -- imagine, for example, that the event from 00:00:01 arrives 2 minutes after the event from 00:00:02.
Rather than trying to implement this with the window API, I would use a KeyedProcessFunction. If you only need to support processing time windows, then these concerns about out-of-orderness do not apply, and the solution can be fairly simple. It suffices to keep one object in keyed state, which might be a list holding all of the events in the window, or a counter or other aggregator, depending on what you're trying to accomplish.
When an event arrives, if the state (for this key) is null, then there is no open window for this key. Initialize the state (i.e., create a new, empty list, or set the counter to zero), and create a Timer to fire at the appropriate time. Then regardless of whether the state had been null, add the incoming event to the state (i.e., append it to the list, or increment the counter).
When the timer fires, emit the window's result and reset the state to null.
If, on the other hand, you want to do this with event time windows, first sort the stream and then use the same approach. Note that you won't be able to handle late events, so plan your watermarking accordingly (reducing the likelihood of late events to a manageable level), or go for a more complex implementation.
I'd like create a class/struct/other that contains each measure of a song, complete with independent tempo and beat count, then play the entire song back (with potential updates from user input). I'm only aware of how to change those variables on an AKSequencer track as a whole; is there a way to store that data independently and then have it play back as one? And keep coherence between the measures so as not to "jump" between them? Thanks!
AKSequencer is not good at setting loop length on the fly, but it is totally fine for adding to or re-writing the contents of a track while the sequencer is running. This includes tempo events.
Why don't you set the length to something arbitrarily long, and string together your MIDI events measure after measure without ever looping? Keep track of how many beats have been written so far, and just keep adding after that point. Doing this while the sequencer is running should be no problem. You could even automate writing the next bar by triggering a callback function near the end of each measure getting it to write the next segment (which could be selected or 'cued up' at run-time). You can schedule the tempo events with addTempoEventAt(), with the starting point for the next segment.
When your user stops the sequence, clear the track(s), reset the tempo, rewind the sequence and start over.
I've been programming a solitaire card game and all has been going well so far, the basic engine works fine and I even programmed features like auto move on click and auto complete when won, unlimited undo/redo etc. But now I've realised the game cannot be fully resumed ie saved so as to continue from the exact position last time the game was open.
I'm wondering how an experienced programmer would approach this since it doesn't seem so simple like with other games where just saving various numbers, like the level number etc is sufficient for resuming the game.
The way it is now, all game objects are created on a new game, the cards, the slots for foundations, tableaus etc and then the cards are shuffled and dealt out. This is random but the way I see it, the game needs to remember this random deal to resume game and deal it again exactly the same when the game is resumed. Then all moves that were executed have to be executed as they were as well. So it looks like the game was as it was last time it was played, but in fact all moves have been executed from beginning again. Not sure if this is the best way to do it but am interested in other ways if there are any.
I'm wondering if any experienced programmers could tell me how they would approach this and perhaps give some tips/advice etc.
(I am going to assume this is standard, Klondike Solitaire)
I would recommend designing a save structure. Each card should have a suit and a value variable, so I would write out:
[DECK_UNTURNED]
H 1
H 10
S 7
C 2
...
[DECK_UNTURNED_END]
[DECK_TURNED]
...
[DECK_TURNED_END]
etc
I would do that for each location cards can be stacked (I believe you called them foundations), the unrevealed deck cards, the revealed deck cards, each of the seven main slots, and the four winning slots. Make sure however you read them in and out, they end up in the same order, of course.
When you go to read the file, a simple way is to read the entire file into a vector of strings. Then you iterate through the vector until you find one of your blocks.
if( vector[ iter ] == "[DECK_UNTURNED]" )
Now you go into another loop, using the same vector and iter, and keep reading in those cards until you reach the associated end block.
while( vector[ iter ] != "[DECK_UNTURNED_END]" )
read cards...
++iter
This is how I generally do all my save files. Create [DATA] blocks, and read in until you reach the end block. It is not very elaborate, but it works.
Your idea of replaying the game up to a point is good. Just save the undo info and redo it at load time.
I've created a music sequence using coreMIDI and AudioToolBox and would now like to display the current beat position of the looped sequence in the UI. If the loop is only four beats, I would like the display to toggle between 1,2,3,4 and return to 1 as the sequence loops (much like in the transport of a program such a Logic Pro). I've made a function that uses MusicSequenceGetBeatsForSeconds() to calculate the beats based on the amount of time (using CFAbsoluteTimeGetCurrent()) that has passed since play was pressed, but this keeps the value increasing linearly (on beat on of the next measure the display reads "5.0"). How do I read the current beat of the sequence?
Skip the end of track message; you can't rely on it.
Instead create a MusicSequenceUserCallback. Then add a track to your sequence that holds user events. The actual data in the event doesn't matter.
var event = MusicEventUserData(length: 1, data: (0xAA))
let status = MusicTrackNewUserEvent(markerTrack, endBeat, &event)
Then in the callback look for this arbitrary data value and do that thing you want to do.
let d = eventData.memory
if d.data == 0xAA {
In Swift 2.2, the callback cannot be a closure. So make it a global function.
Look at MuscPlayer's MusicPlayerGetTime function instead.
Depending on what you want to do, you can set up a virtual destination as an endpoint for your MusicSequence and in its read block respond to events as they happen.
This might seem like a pretty obvious question, but I've been combing through Apple's documentation and can't seem to find a straight answer.
What actually happens when a turn times out - that is to say, the time interval passed as the turnTimeout parameter to endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: has passed? Logic dictates that either there would be a callback similar to handleTurnEventForMatch:didBecomeActive: to explicitly handle no move being made, or the next player in the nextParticipants array would receive a turn notification.
Unfortunately, although Apple are quite happy to describe how turnTimeout limits how long a player has to act (and to tell you that it's up to your game to decide how to handle this), there's no information about what methods are called or what data is supplied, and I'm seeing some very odd behavior - namely the player who passed is getting a handleTurnEvent notification with the same match data as the turn they just timed out on. Anyone have any advice?
Apple's documentation on what it does:
If the next player to act does not take their turn in the specified
interval, the next player in the array receives a notification to act.
This process continues until a player takes a turn or the last player
in the list is notified.
In the case of a 2 player match, at least during testing, nothing actually happens. If P1 plays a turn the list of next participants looks like [ P2, P1 ]. If P2 times out, P1 should get notified as it is the last one in the list, however P1 just went, Apple must consider "end of the list" as when you get back to the person that last played and not when you actually run out of people. This prevents people from playing two turns in a row. Although is not what I would expect to happen based on the documentation. I have not tested this in a 3+ player game.