Changing instruments in midi encoding? - java

I'm trying to write a function to dynamically create midi files on Android. Since there is no javax.sound.midi library I'm just writing the bytes out to file myself. I've found some great guides (see below) so I've been able to create multiple track midis. However I haven't been able to figure out how to switch instruments for any of the tracks so everythign is just using the default instrument.
I think from the documents I read the code I need is to "program change" followed by the program number.
What I've tried so far is writing the following out to a byteoutputstream array:
track.write((byte) 192); // 128 + 64
track.write((byte) x); // x is the instrument number between 1-128.
I've put this before the start of the note on/ note off track information, but it doesn't seem to do anything except make the midi take a long time to start. Am I on the right track here, or am I missing something? Any help is appreciated.
http://faydoc.tripod.com/formats/mid.htm
https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html

Finally figured it out. It was a just a simple thing, but I forgot to include track time before the program change. Once I added the 0 byte it worked.

Related

Add and trace unhearable Noises or Markers to a Video Clip

I'm trying to write an application which adds some noises (or markers) to various parts of a Video Clip and trigger an action once a section (marker) been reached.
I think using technologies like Audio Stenography cannot help this purpose. As far I understood it, It hides a text value in unused sections of a WAV file and extract them from a file.
I also learned that any frequencies under 20 Hz and upper 20KHz cannot be heared by a human ear. Using a Audio Analysis library like musicg,
gave me an idea to recognize and encode those frequencies with some algorithms like FFT and trigger an action based on that encoded unhearable frequency.
That was all I could find out after a week of investigation and unfortunately don't know further and will appreciate if somebody have had a similar experience in this field and can help me.

vlcj mlr special character

I have been stalking this great site for ages. Today I finally decided to create an account when I got stuck on a problem.
My problem is rather basic vlcj executing. I have a program running as an audio player. It is all done except for one problem I cannot seem to figure out.
When someone tried to play a song with a 'é' (e with acute) in the filepath, it seems to translate wrong into the system of vlcj.
Example:
I run:
mediaPlayerComponent.getMediaPlayer().playMedia("file:///C:\\test.mp3");
//(where mediaPlayerComponentis my is my local instantiated
// EmbeddedMediaPlayerComponent)
And this plays fine. But if I run:
mediaPlayerComponent.getMediaPlayer().playMedia("file:///C:\\é.mp3");
It does not run anything.
If I call startMedia instead of playMedia, the boolean return value is false.
I also tried it without the 'file:///' in front of it, this doesnt functionally change a thing, except if I kill the program, then I get a 'libdvdread' error messages such as:
libdvdread: Could not open C:\?.mp3 with libdvdcss.
So to make the question short and sweet: How do I supply the correct 'mrl' to make vlcj play my 'é.mp3'. And/or which MediaOptions are needed to parse the correct encoding (I am assuming my error is here?)
Preemptively sorry for not supplying an SSCCE, I do not think it will be relevant.
Thank you for your time.
After some interlude I finally found out what went wrong. Apperantly, under windows international characters arent really parsed very well into VLCJ. By adding:
<jvmarg value="-Dvlcj.log=DEBUG>
to my ANT-run script, I suddenly could play files with an e-acute. Apperantly the decoder of the JVM is finalized when initializing.
Hope this helps someone :-)
This is transparently handled in vlcj 2.4.0 onwards by detecting local filenames that contain Unicode characters and converting those filenames to percent-encoded file URLs.
So with current versions of vlcj you should be able to simply pass your filename containing international characters directly to mediaPlayer.playMedia(...).
I found the solution here:
https://github.com/caprica/vlcj/issues/415
This work for me on mac and on windows (vlcj-3.7.0) :
public void play(String mrlPathFile) {
// URI encode for avoid non ascii character problem in windows!!!
mrlPathFile = new File(mrlPathFile).toURI().toASCIIString().replace("file:/", "file:///");
mediaPlayer.playMedia(mrlPathFile);
}
I this could help anyone :)

Using JAudioTagger to get track duration?

I'm trying to use JAudioTagger in a media player like application to yoink the meta data for each song, but I don't see a field for track duration. I'm sure there must be one but I can't seem to find it and a couple searches haven't turned up anything. I'm looking at: http://www.jthink.com/jaudiotagger/tagmapping.html and at the java docs.
Does anyone have any idea? Thank you for any help!
As the earlier answer said the track length is not stored in the tag but can be derived from the audio itself, this is why it is accesible via the audioheader object rather than the tag itself i.e.
AudioFile audioFile = AudioFileIO.readFile("/somefile.mp3");
System.out.println(audioFile.getAudioHeader().getTrackLength());
If it is an mp3, you can all get the tracklength output nicel formatted as mm:ss
System.out.println((Mp3AudioHeader)audioFile.getHeader().getTrackLengthAsString());
or
new MP3File("/somefile.mp3").getMP3AudioHeader().getTrackLengthAsString();
For most formats, the length isn't in the tag.
Many libraries (and media players), like TagLib, estimate it for you by working out the length in seconds of a few hundred kilobytes of the file (the bitrate) and multiplying up. Sometimes this goes horrendously wrong, but, a surprising portion of the time, it works out fine.
I can recommend mp4parser library since it returns duration with expected precision (like ffmepg does).

Change the volume of an audio file and save the file using java.sound.sampled

I want to change the volume of an audio file
and save the new file using java.sound.sampled.
I tried to use the mixer to create a source line
from the file given and a target line to the new file.
So that I can change the mixer settings to change the volume.
But the sound is being played to the system speaker.
Am I thinking along correct way or not?
Is there any other way to record a file from a line?
The code is available here
A solution I got is www.jsresources.org/examples/AmplitudeConverter.html.
But can the same be done within java.sound.sampled
without using external libraries.
To change the volume, if you don't use a "Control" (see the Java Sound Tutorials), there is the option of directly modifying the samples themselves.
In your innermost loop, convert the bytes in the innermost buffer into a sample (if it is WAV 16-bit encoding, then you need to put the two bytes together to make the single SHORT value), then multiply that value by a float that ranges from 0 to 1, where 0 is the quietest and 1 leaves the sound at full volume. Then take the result and break it back down into two bytes and pass it along.
Do you need the code to do this? There are several other posts here where folks convert from bytes to INTs or Float and back.
Hmmm. This question is pretty old. Well maybe my answer will help someone new to the same problem.

Audio playing too fast

If any of my fellow Xuggler users can tell me what I'm doing wrong, that would be awesome! I am doing the following:
Reading from ogv (ogg video)
Queueing the audio and video
Writing back to ogv
sounds simple right? The problem I am experiencing in my QueueMixer class is that the output file plays the audio 2x too fast, and no matter what I check or change with regards to pts it doesnt improve.
The eclipse project and all files being used are at this link:
http://dl.dropbox.com/u/7316897/paul-xuggled.zip
To run a test, compile and execute the StreamManager class; a test ogv file is included. Before anyone asks, yes I have to queue the data as it will be mixed with other data in a future version.
Audio has a sample rate. Make sure that you copy the sample rate from the input to the output, otherwise the system might use a default (like 44KHz while the original data was sampled at 22KHz which would create such an effect).
The fix is to multiply the sample count by two when extracting them from the ShortBuffer.
samples = new short[(int) audioSamples.getNumSamples() * 2];
audioSamples.getByteBuffer().asShortBuffer().get(samples);
Having half the samples causes the audio to play twice as fast.

Categories

Resources