 |
|
 |
Hello,
I'm starting to convert your project from MFC to SmartWin++.
I would like to know if I'm allowed to include it in a future version of the my IDE (http://sallyide.sourceforge.net[^]) as an example project or if there are some restrictions.
P.S. At the present time, I'm at a good point (http://sallyide.sourceforge.net/screenMidiPlayer.jpg[^]), even if I think I won't implement the master volume (I can't understand how it's done) and my "Reverb" button does not seem to work on my system (maybe it's just a question of "Synthetizer").
Regards, Flix.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Of course, you are completely allowed to include it (I'm aware you are refering to CMidiMusic class) in your IDE related project, even the DirectMIDI library .
You don't have to pay anything in return, however, some acreditation in your project would be grateful (I don't eat air ).
Good luck with your great project! Maybe someday I make use of it. Who knows!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
hi i just read the cMidiDemo article and needed something with more "performance" features so i decided to read this stuff about directx.
i'm a newb so i dont really need much info on performance at the moment. but what i do need is some sort of strp by step guide on how to set these projects up in msvc++ and run them. basicaly i need lots of help on starting up apps so i can get comfortable with an IDE. can someone please help?
any links to midi related tutorials with such features?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Your code is very nice. I use it to my program but I want to ask you somthing. I want to know can I convert miditime that i get it like "Tick value" to real time(how long this song play). I just to show how long of the song like in winam or media player. Thank you!!!!!!!!!1
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thank you for appreciating this old piece of code.
First off, if you want to get the length of a music segment you will have to call IDirectMusicPerformance8::MusicToReferenceTime(MUSIC_TIME mt,REFERENCE_TIME *rtSegTime) after the call to CMidiMusic::GetLength(MUSIC_TIME *mt) that will give you the length of the sequence in ticks. Once you have it all, you must proceed to convert the rtSegTime variable which is a 64-bit value returned by the master clock and is incremented every 100 ns to common time. So, you must start making calculations to solve the duration in hours, minutes and seconds: These formulas may help you:
REFERENCE_TIME rtTime = rtSegTime / 10000000;
unsigned int hours = (unsigned int)(rtTime / 3600);
rtTime %= 3600;
unsigned int minutes = (unsigned int)(rtTime / 60);
rtTime %= 60;
unsigned int seconds = (unsigned int)rtTime;
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
Thank you for your reply. I just find a little bug in your program and i need your help again. When use pause button some note was skipped. Could you plese help me to fix this problem. I found that note skipped is relative with tempo.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello Carlos,
the CMidiMusic class is great. I have written a simple Midi file editor using CMidiMusic to playback a Midi file. When the Midi file gets changed and the user wants to listen to the changes, I tried loadind the Midi file again. This didn't work because DirectMusic seems to have a lock on the old Midi file. When I destroy my instance of CMidiMusic and create a new instance it works fine. Since I neither know the internals of CMidiMusic nor the internals of DirectX. I wanted to know if this is a safe way to use CMidiMusic.
Michael J. Mueller
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Of course. There is not any other alternative at this abstraction level because the IDirectMusicLoader8::LoadObjectFromFile locks the file completely and doesn't allow any other shared access to the resource. Therefore, your solution could be valid at object oriented level, though it would be better to use the audio part of the DirectMidi library to get it, since it allows to migrate from the CDirectMusic object level to a more accuracy DirectX/DirectMusic API level using CSegments wrapped objects. Unfortunately, in DirectMusic is hard to access to the IDirectMusicSegment internals in order to modify MIDI commands and music data, otherwise, your problem could be solved in a smart way. You could also work with allocated memory, making all the modifications in a memory space dedicated to store modified MIDI data and, finally, saving it to disk. This approach could be, more or less, -use files only when needed-, not like an intuitive operation.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'm using MCI to playback MIDI for a game. Having all my music parts in the same midi file has worked great till Win XP, where suddenly MCI_OPEN delays proportional to the file size, in my case 20 seconds to load.
Resorting to DirectMusic to solve the problem but would do fine with the low level API found in WINMM.DLL which works perfectly without any delays. But here's the problem. When setting a start position the music doesn't start where it should. Having checked the exact time position in a several midi editors, setting the start pos doesn't work, even if adjusting the position +- a few seconds. This worked fine in earlier versions of MCI, Win 95/98.
Any help appreciated.
wanders
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'm also a little confused about your questioned problem. You said you are using MCI for playing MIDI music for a game. Then you said that the MCI_OPEN command suddenly delays the amazing amount of 20 seconds to load the MIDI sequence. Why is that? Other related questions to find out the cause: Are you using DirectMusic via DirectMIDI? otherwise, which interface method are you invoking?
Please, I request you to be as explicit as possible when descibing the problem. Thank you.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thank for the quick reply.
I'm not using DirectMusic yet. The MCI_OPEN delay is a bug in Win XP/NT also described by AXELMUELLER on 'the code project' (http://www.codeproject.com/audio/mididemocp.asp) At the end of the article...
I'm currently testing the other option as he descibes MMSYSTEM, midiOutxxx() and midiStreamxxx() and it runs perfectly except for the problem setting the correct start position.
For example, I have several music parts in the midi file and the second part start at say, 3.38.000. When playing the file from the beginning all parts start where they should. If setting the start position directly to 3.38.000 nothing happens. If I set the start pos to 3.30.000 and play from there it's quiet at 3.38.000 and after. Even stranger, some other music part in the file plays correctly when setting their start pos. I've tried both with midi format 0 and 1.
wanders
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It's a very strange problem. I don't know very much about MMSYSTEM midi commands so I can't be very helpful for you. Nevertheless, I suggest you to use the CMidiMusic class to discard any problem in the MIDI file or the program logic. Use the HRESULT CMIDIMusic::Seek(MUSIC_TIME mtMusicTime)method to check it. It should work fine.
cheers Carlos.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The standard MIDI file specification has provision for multiple ports to overcome the 16 channel limitation of a single port.
I have several MIDI files that are encoded for multiport use, but they can only be played from within a MIDI seqeuncer that supports multiple ports.
I would very much like to write a MIDI file player that supports multiport MIDI files, however, DirectMusic loads the entire MIDI file into a single segment and does not allow one the opportunity to modify which track goes to which port.
Am I missing something? How would you go about implimenting this scenario?
Thanks for your time and effort.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Eddie,
The solution is not easy in any case. First off, DirectMusic architecture doesn't support multiple ports in an "easy to code" way because it hasn't got any track information related to device or ports. You might have two alternatives:
The first one is to develop a MIDI file reader and parser that extracts the ports assigned to MIDI channels and then, programming the player from the scratch using multiple directmidi::COutputPort objects.
The second alternative is also to develop a MIDI file reader and parser and then using directmidi::CPortPerformance::AssignPChannel to route a specific performance channel to another port. In this approach, you must manually download the instrument from the MIDI file to the performance channel in order to play in a different non-default port.
cheers
PS.
You can obtain a MIDI reader toolkit from the Stanford University at:
http://ccrma.stanford.edu/software/stk/[^]
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanks for the response Carlos.
I am familiar with parsing MIDI files and I am familiar with port handling in DirectMusic, it's getting MIDI messages into segments programmatically that has me stumped.
Thanks again.
Cheers Eddie
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Carlos-
I'm interested in discussing with you the possibility of having you develop some audio software for us on a contract basis. Could you please contact me at: pt@NO_SPAMpower-t.com .
Thanks,
Paul T.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
does someone know how to retrieve the length of a midi-file in seconds or milliseconds? for some midi-files it's totalticks/768, for others it's totalticks/768/x, where x is some obscure factor.
GetGlobalParam(GUID_PerfMasterTempo,... doesn't work because it's not that x (despite the fact, that you have to call SetGlobalParam() once to be able to user GetGlobalParam()).
any ideas?
*Update*
I've found the following VB Code elsewhere on the Net, but I can't find similar Functions in the C++ Interfaces of my DirectMusic Documentation. Is it possible to translate that into C++?
'Play the segment just long enough to get the info mtTime = perf2.GetMusicTime() Call perf2.PlaySegment(seg, 0, mtTime + 2000)
'GetTempo dTempo = perf2.GetTempo(mtTime + 2000, 0) lblTempo.Caption = "Tempo: " & Format(dTempo, "00.00")
'GetTimeSig Call perf2.GetTimeSig(mtTime + 2000, 0, timesig) lblTimeSig.Caption = "Time Sig: " & timesig.beatsPerMeasure & "/" & timesig.beat
'GetLength mtLength = (((seg.GetLength() / 768) * 60) / dTempo) 'This is an important set of numbers, this'll result in the total 'number of seconds the file lasts.
:wq
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Rüpel,
Those formulas are right. If you analyze the last one, you can take notice that seg.GetLength() is the number of ticks your segment lasts, understanding that the ticks are incremented DMUS_PPQ times for each quarter-note where DMUS_PPQ is defined as 768 ticks/(1 beat = 1 quarter note).
Therefore, if your MIDI sequence returns 301558 ticks in the count, for example, you'll have 301558/768 = 392.65 quarter notes in your sequence.
Then, you will have to obtain the tempo of your sequence (remember that your sequence can have several tempo changes). If you observe the tempo changes in a sequencer, you can obtain the total time in minutes if you divide the number of quarter notes by the BPM's or beats per minute. Therefore, if you have 392.65 beats in your MIDI and 98 BPM, the total minutes will be 392.65/98 = 4 minutes x 60 = 240 seconds.
If you decide to apply this formula you will have to obtain the tempo in each MUSIC_TIME (ticks) of yor sequence. To perform it in C++, you will have to retrieve the GUID_TempoParam parameter using either IDirectMusicSegment8::GetParam or IDirectMusicPerformance8::GetParam and providing the current MUSIC_TIME of your sequence to achieve it.
Regards.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello, I have pieces of midi music which change tempo very frequently. What is the best way to obtain the length inside a program? Is there a better way than calling GetParam hundreds of thousands of times? How does something like Windows Media Player do it? If I load up a midi, it knows right away how long the pieces is...
Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Personally, I've never tried to call GetParam thousands of times to get tempo changes, it would be a madness, besides it's against the system performance. If I were you, I would read part of the MIDI file to obtain the tempo track and finally read the tempo marks inside it to use them for your time seeking calculation.
This URL may help you:
http://www.borg.com/~jglatt/tech/midifile.htm[^]
-- modified at 10:20 Sunday 26th November, 2006
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi thanks for your response. How do I go about finding which track is the tempo track?
And once I find the tempo track, aren't I going to have to call GetParam and pass the track # in?
Even without knowing which track is the tempo track, if I am calling GetParam to get the tempo, and pass in DMUS_SEG_ANYTRACK, isn't it going to apply to the tempo track anyway?
In other words, is it going to save me any trouble to know which track is the tempo track? Won't I still have to read through it using GetParam?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Your tutorial is excellent and thanks for a convenient class to play MIDI. I'm trying to make a player that can show up the lyrics of the MIDI (if it has). How can I extract the lyrics and the time-stamp of each word to show up on screen correctly corresponding to the note like Vanbasco Player?
Please help me out!
|
| Sign In·View Thread·PermaLink | 1.67/5 (3 votes) |
|
|
|
 |
|
 |
Hi,
The solution is not very simple with DirectMusic. I suggest you to program a DirectMusic Tool using the IDirectMusicTool8 interface and the IDirectMusicTool8::GetMediaTypes method with the DMUS_PMSGT_LYRIC capture parameter in the call. Then, you must also modify the sample code "DirectMusic\MusicTool" that comes with the DirectX SDK and explains how to handle this feature.
The other alternative is to make a simple MIDI file reader that handles with the lyric event track.
Regards.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
 |
Hi Carlos,
Thank for your quick reply, it seems more complicated than i thought I have one more question for your advice, if i have already got the time-stamp and word of each meta lyric event (possibly store in a array) then is this possible to synchronize the word using Window timer if i know the bpm (beat per minute) of the midi file?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |