Music21: Strip empty data at end of written midi file - music21

I am writing a simple midi file using music21:
import music21
stream = music21.stream.Stream()
n = music21.note.Note(60)
n.duration.type = 'half'
stream.insert(0, n)
stream.write('midi', 'out.midi')
This plays middle c for half a measure. However, the resulting file contains empty space for the remainder of that measure:
Is there a way to remove that trailing "whitespace"?

The current version from PyPI (7.1.0) seems to always add one quarter note of silence at the end. This can be changed by setting music21.defaults.ticksAtStart, despite its name. The units are MIDI ticks defined by music21.defaults.ticksPerQuarter. The default value of both is 1024.
Be aware that some MIDI players will stop synthesizing when the file ends, so the sound will stop dead when the last note is released instead of dying away if there is no padding.
Also, some players may pad to a measure boundary no matter what you do. There is no way to encode a pickup measure in MIDI, other than inserting rests.

Related

How to dynamically change the string from the i/o stream in c

I was looking at a problem in K&R (Exercise 1-18), which asked to remove any trailing blanks or tabs. That pushed me to think about text messengers like Whatsapp. The thing is lets say I am writing a word Parochial, then the moment I had just written paro, it shows parochial as options, I click on that replaces the entire word (even if the spelling is wrong written by me, it replaces when I chose an option).
What I am thinking is the pointer goes back to the starting of the word or say that with start of every new word when I am writing, the pointer gets fixed to the 1st letter & if I choose some option it replaces that entire word in the stream (don't know if I'm thinking in the right direction).
I can use getchar() to point at the next letter but how do I:
1: Go backward from the current position of the pointer pointing the stream?
(By using fseek())?
2: How to fix a pointer a position in an I/o stream, so that I can fix it at the beginning of a new word.
Please tell me my approach is correct or understanding of some different concept is needed. Thanks in advance
Standard streams are mainly for going forward*, minimizing the number of IO system calls, and for avoiding the need to keep large files in memory at once.
A GUI app is likely to want to keep all of its display output in memory, and when you have the whole thing in memory, going back and forth is just a simple mater of incrementing and decrementing pointers or indices.
*(random seeks aren't always optimal and they limit you from doing IO on nonseekable files such as pipes or sockets)

Fseek to a line number (with lines of variable length)

I have a large file (~10GB) with variable length lines, and I would like to programmatically go to different line numbers. Is there an efficient way to do so?
Yes: build an index. For example, just once you can create a text file on the side which contains the byte offset of various line numbers, like this:
line,offset
0,0
10000,48272
20000,93726
Etc. Then when you want to go to line 13043, just jump to offset 48272 and skip another 3043 newlines. Simple and efficient.
Another approach would be to make your line lengths constant. This would work well if they already have similar lengths so you don't waste too much space. You can pad them out with \0 characters or spaces or whatever, then index the file like a big matrix (line N is at N*LEN bytes).
Finally, you could simply write the line numbers at the beginning of the lines themselves. Then just binary-search within the file, skip to a newline, and inspect the next line number to know whether to look backward or forward (and even guess by how much).
There is no efficient way to do so. You need to scan the entire file once to memorize when are the end of line markers.
Pragmatically, you need a large loop on e.g. getline(3)
You could memoize e.g. the offset of every 100 line, perhaps in a big array or some indexed file using GDBM or some Sqlite database.
My feeling is that you should not have such a huge text file in the first place at all (having a huge text file accessed randomly is the symptom of something wrong). It is not an efficient way to store such data, if you need to access it randomly. You could for example predigest it to fill some database, etc... Probably you should not put such a large piece of data in a text file, but directly in a database or whatever.
Not directly with fseek since it's only capable of moving the position by a bytes amount.
If the efficiency requirement comes from the fact that you must do it many times back and forth a simple solution could be to scan the whole file once and compute all the lines length, store them in a map or array and then use the values to move exactly where you want.

LabVIEW 2009 holding onto data when I don't want it to

I'm new to LabVIEW but have been building a signal analyser code that takes the required data and prints it out to text files after the data has been taken. The problem I'm having is that when it makes a new file it holds on to the data from the previous run and prints that too which is not what I want. I've attached the LabVIEW vi (ver.2009), and any help with this would be greatly appreciated.
Also if someone knows a better way of RMS-ing the data after each iteration than my mess of shift registers I'd be happy to see it.
frequency analyser (fixed).vi
To answer your main question: the part of the code that builds the string (for loop with a shift register) stores the previous data each time you re-run the vi. What you need is to initialise the shift register with an empty string :
Also a couple of notes/suggestions:
You could avoid using shift registers in this case. Divide the DAQ part of the code into say 3 parts: acquire data in the first for loop (store into array), modify the array (you could then perhaps use the build-in RMS vi), visualise on the UI
Build the code in smaller chunks, use subVi's
Keep the code small, nice and tidy (check coding standards), add comments - this will really help you later
Since you asked for advice on the RMS functionality you used I took a more detailed look of your code. And I may be harse, but it doesn't make sense (point by point):
You ask the end user for a number of runs, and then you subtract one. Why? I guess it's because the read data before the for loop. (remove that one).
The Frequency RMS function you use has support for avaraging, and has no limit of the number of averages. Specify the following configuration:
This will add RMS avaraging to you output data, and you can loose all your own calculation with shift registers.
The following code is just plain wrong:
You only shift the data, without actually changing the data. By incrementing the starting frequency you shift the FFT. So a signal that was detected at 55 Hz, no is plotted at 56 Hz. To your end user this is misleading.
One thing you need to be aware of in your code is that you don't have continious sampling. Each iteration of you for loop your data acquisition is started and stopped. You can verify this by plotting the t0's of the waveform that is captured. You'll notice they don't start at a constant interval.
A better aproach is to use the task created by the Express VI in the first iteration:
.
However you should then change the acquisition mode to 'continious samples':
Do not forget to close the task in the last iteration:
Instead of the shift register, you should work with an array which you empty before each run.

characters from a stream

this question was asked in an interview..
assume your computer is reading characters one by one from a stream (you don't know the length of the stream before ending). Note that you have only one character of storage space (so you cann't save the characters you've read to a something like a strong). When you've finished reading you should return a character out of the stream with equal probability.
how to approach this problem?? any idea??
any way to slove this??
It's one of those tricks that you either know or don't:
Take the first character, with probability 1/2 take the next one, otherwise keep the first one, with probability 1/3 take the next one, otherwise keep, etc.
It works because every time you pick the n th char with probability of 1/n, or keep the previous one (that had probability 1/(n-1) to be there) with probability (1-n)/n, and the 1-n s cancel.

Reuse of characters in compiled .exe file

Once long ago, out of curiosity, I've tried hex-editing the executable file of the game "Dangerous Dave".
I've looked around the file for any strings I could find, and made some random edits to see if it would actually change the text displayed within the game.
I was surprised to see the result, which I have now recreated using a hex-editor and DOSBox:
As can be seen, editing the two characters "RO" in the string "ROMERO" resulted in 4 characters being changed, with the result becoming "ZUMEZU". It seems as if the program is reusing the two characters and prints them at the start and end of that string.
What is the cause of this? My first guess would be trying to make the executable smaller but just the code that reuses the characters would probably require more space than those 2 bytes to be saved.
Is it just a trick done by the author, or just some compiler voodoo?
Tricky to say for sure without reverse-engineering, but my guess would be that a lot of the constant data in the program is compressed using an algorithm from the LZ family. These compression schemes work essentially in the way that you've observed: they encode repeated substrings as references to text that has previously been decoded.
These compression algorithms were probably used for more than just this one string, and not just for text either; it's quite possible that they were also used to compress other data, such as graphics or level layouts. In short, there were probably significant savings made by using this algorithm!
The use of these compression algorithms is common in older games as a way of saving disk space, but was not automatic - the implementation of this algorithm would likely have been something Romero added himself.

Resources