- •Обробка виключних ситуацій
- •6.0804 “Комп’ютерні науки”
- •1. Мета роботи
- •2.Основні теоретичні відомості
- •2.1. Оператори мови java
- •15.1. Модель обробки "поставщик-споживач"
- •15.2. Класи-фільтри
- •15.6. Модель обробки прямим доступом
- •15.7. Перетворення зображення в Java 2d
- •15.8. Афінне перетворення зображення
- •15.9. Зміна інтенсивности зображення
- •Import java.Awt.*;
- •Import java.Awt.Image.*;
- •Import java.Awt.Event.*;
- •15.10. Зміна складових кольору
- •15.11. Створення різних эфектів
- •Import java.Awt.*;
- •Import java.Awt.Event.*;
- •15.13. Покращення зображення подвійною буферизацією
- •50, 50, 0, 360, Arc2d.Open));
- •15.14. Звук
- •Import java.Applet.* ;
- •Import java.Net.*;
- •15.15. Програвання звуку в Java 2
- •Import javax.Sound.Sampled.*;
- •Import java.Io.*;
- •If (!AudioSystem.IsLineSupported(info)){
- •Import javax.Sound.Sampled.*;
- •Import java.Io.*;
- •If (!AudioSystem.IsLineSupported(info)){
- •Import javax.Sound.Midi.*;
- •Import java.Io.*;
- •15.16. Синтез і запис звуку в Java 2
- •Import javax.Sound.Midi.*;
- •Import java.Io.*;
- •3.Контрольні запитання
- •4.Лабораторне завдання
- •Мета роботи.
- •Список рекомендованої літератури
Import javax.Sound.Midi.*;
Import java.Io.*;
class PlayMIDK{
PlayMIDK(String s) {
play(s);
}
public void play(String file){
try{
File f = new File(file);
// Отримуємо секвенсор по замовчуванню
Sequencer sequencer = MidiSystem.getSequencer();
// Перевіряємо, чи отриманий секвенсор
if (sequencer == null) {
System.err.println("Sequencer is not supported");
System.exit(0);
}
// Відкриваємо секвенсор
sequencer.open();
// Отримуємо MIDI-послідовність із файла
Sequence seq = MidiSystem.getSequence(f);
// Направляємо послідовність в секвенсор
sequencer.setSequence(seq);
// Починаємо програвання
sequencer.start();
// Тут треба зробити затримку на час програвання, а потім зупинити:
try{
Thread.sleep(67000);
}catch(InterruptedException e){}
sequencer.stop();
}catch(Exception e){
System.err.println(e);
}
}
public static void main(String[] args){
String s = "doom.mid";
if (args.length > 0) s = args[0];
new PlayMIDK(s);
}
}
15.16. Синтез і запис звуку в Java 2
Синтез звуку заключається в створенні MIDI-послідовності - обєкта класу sequence — яким-небудь способом: з мікрофона, лінійного входа, синтезатора, із файла, або просто створити в програмі, як це робиться в лістинзі 15.18. Спочатку створюється пуста послідовність одним із двох конструкторів:
Sequence(float divisionType, int resolution)
Sequence(float divisionType, int resolution, int numTracks)
Перший аргумент divisionType визначає спосіб відрахунків моментів (ticks) MIDI-подій — це одна із констант:
PPQ (Pulses Per Quarter note) — відрахунки заміряються в долях від тривалості звуку в чверть;
SMPTE_24, SMPTE_25, SMPTE_so, SMPTE_30DROP (Society of Motion Picture and Television Engineers) — відрахунки в долях одного кадра, при указаному числі кадрів в секунду.
Другий аргумент resolution задає ккількість відрахунків у вказану одиницю, наприклад,
Sequence seq = new Sequence)Sequence.PPQ, 10);
задає 10 відрахунків у звуці тривалістю в чверть. Третій аргумент numTracks визначає конструктор дорожок в MIDI-послідовності. Потім, якщо застосовувався перший конструктор, в послідовності створюється одна або декілька дорожок:
Track tr = seq.createTrack();
Якщо застосовувався другий конструктор, то треба отримати уже створені конструктором дорожки:
Track[] trs = seq.getTracks();
Потім дорожки заповнюються MIDI-подіями за допомогою MIDl-подій. Єсть декілька типів повідомлень для різних типів подій. Найчастіше зустрічаються події типу shortMessage, які створюються конструктором по замовчуванню і потім заповнюються методом setMessage():
ShortMessage msg = new ShortMessage();
rasg.setMessage(ShortMessage.NOTEJDN, 60, 93);
Перший аргумент указує тип повідомлення: NOTE_ON - почати звучання, NOTE_OFF - зупинити звучання і т. д. Другий аргумент для типу NOTE_ОN показує высоту звуку, в стандарті MIDI це числа від 0 до 127, 60 - нота "до" першої октави. Третій аргумент означає "швидкість" натискання клавіші MIDI-інструмента і по-різному розуміється різними пристроями. Далі створюється MIDI-подія:
MidiEvent me = new MidiEvent{msg, ticks);
Перший аргумент конструктора msg — це повідомлення, другий аргумент ticks - час наступу події (в нашому прикладі програвання ноти "до") в одиницях послідовності seq (в нашому прикладі в десятих долях чверті). Час відраховується від початку програвання послідовності. Нарешті, подія заноситься на дорожку:
tr.add(me);
Указані дії продовжуються, поки всі дорожки не будуть заповнені всіма подіями. В лістинзі 15.18 це робиться в циклі, але звичайно MIDI-події створюються в методах обробки натискання клавіш на звичайній абои спеціальній MIDI-клавіатурі. Ще один спосіб — вивести на екран зображення клавіатури і створювати MIDI-події в методах обробки натискання кнопки миші на цій клавіатурі. Після створення послідовності її можна програвати, як в лістинзі 15.17, або записати у файл або вихідний потік. Для цього замість методу start() треба застосовувати метод startRecording(), який одночасно і програє послідовність, і готує її до запису, яку здійснюють статичні методи:
write(Sequence in, int type, File out)
write(Sequence in, int type, OutputStream out)
Другий аргумент type задає тип MIDI-файла, який краще всього визначити для заданної послідовності seq статичним методом getMidiFiІeTypes(seq). Даний метод повертає масив можливих типів. Треба скористатися нульовим елементом масиву. Все це показано в лістинзі 15.18.
Лістинг 15.18. Створення MIDI-послідовності нот звукоряду