Skip to content

Commit a8bd9fb

Browse files
author
haebin
committed
missing files added.
1 parent 7b22bec commit a8bd9fb

3 files changed

Lines changed: 484 additions & 0 deletions

File tree

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
package com.google.api.services.samples.youtube.cmdline.partner.cuetone.audio;
2+
3+
import java.awt.BorderLayout;
4+
import java.awt.FlowLayout;
5+
import java.awt.GridLayout;
6+
import java.awt.event.ActionEvent;
7+
import java.awt.event.ActionListener;
8+
import java.beans.PropertyChangeEvent;
9+
import java.beans.PropertyChangeListener;
10+
import java.lang.reflect.InvocationTargetException;
11+
12+
import javax.sound.sampled.AudioFormat;
13+
import javax.sound.sampled.AudioInputStream;
14+
import javax.sound.sampled.DataLine;
15+
import javax.sound.sampled.LineUnavailableException;
16+
import javax.sound.sampled.Mixer;
17+
import javax.sound.sampled.TargetDataLine;
18+
import javax.sound.sampled.UnsupportedAudioFileException;
19+
import javax.swing.JButton;
20+
import javax.swing.JCheckBox;
21+
import javax.swing.JFrame;
22+
import javax.swing.JLabel;
23+
import javax.swing.JPanel;
24+
import javax.swing.JScrollPane;
25+
import javax.swing.JTextArea;
26+
import javax.swing.JTextField;
27+
import javax.swing.SwingUtilities;
28+
import javax.swing.UIManager;
29+
import javax.swing.border.TitledBorder;
30+
31+
import org.slf4j.Logger;
32+
import org.slf4j.LoggerFactory;
33+
34+
import be.tarsos.dsp.AudioDispatcher;
35+
import be.tarsos.dsp.AudioEvent;
36+
import be.tarsos.dsp.AudioProcessor;
37+
import be.tarsos.dsp.io.jvm.JVMAudioInputStream;
38+
import be.tarsos.dsp.pitch.PitchDetectionHandler;
39+
import be.tarsos.dsp.pitch.PitchDetectionResult;
40+
import be.tarsos.dsp.pitch.PitchProcessor;
41+
import be.tarsos.dsp.pitch.PitchProcessor.PitchEstimationAlgorithm;
42+
import be.tarsos.dsp.util.fft.FFT;
43+
44+
import com.google.api.services.samples.youtube.cmdline.partner.LiveAdsManager;
45+
46+
public class CueApp extends JFrame implements PitchDetectionHandler, LogViewer {
47+
final static Logger logger = LoggerFactory.getLogger(CueApp.class);
48+
49+
/**
50+
*
51+
*/
52+
private static final long serialVersionUID = -1775769919742366157L;
53+
54+
private final SpectrogramPanel panel;
55+
private AudioDispatcher dispatcher;
56+
// private Mixer currentMixer;
57+
private PitchEstimationAlgorithm algo;
58+
private double pitch;
59+
60+
private float sampleRate = 44100;
61+
private int bufferSize = 1024;
62+
private int overlap = 256;
63+
// private int bufferSize = 1024 * 4;
64+
// private int overlap = 768 * 4 ;
65+
66+
private JTextArea logViewer;
67+
private JTextField channel = new JTextField(12);
68+
private JTextField contentOwner = new JTextField(10);
69+
private JTextField video = new JTextField(5);
70+
private JTextField adsNumber = new JTextField(2);
71+
private JTextField adsDuration = new JTextField(3);
72+
private JCheckBox verboseLog = new JCheckBox("Verbose");
73+
74+
private LiveAdsManager adsManager = new LiveAdsManager();
75+
private PitchDetectionHandler pitchHandler = new DTMFSignalHandler(
76+
adsManager, this);
77+
78+
private boolean verbose = false;
79+
80+
public CueApp() {
81+
logger.info("YT Live Ads Man started. --------------------------------------------------");
82+
this.setLayout(new BorderLayout());
83+
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
84+
this.setTitle("YT Live Ads Man");
85+
panel = new SpectrogramPanel();
86+
algo = PitchEstimationAlgorithm.FFT_YIN;
87+
88+
// JPanel pitchDetectionPanel = new PitchDetectionPanel();
89+
logViewer = new JTextArea(10, 30);
90+
logViewer.setEditable(false);
91+
JScrollPane logPanel = new JScrollPane(logViewer);
92+
logPanel.setBorder(new TitledBorder("Logs"));
93+
94+
JPanel inputPanel = new InputPanel();
95+
96+
inputPanel.addPropertyChangeListener("mixer",
97+
new PropertyChangeListener() {
98+
@Override
99+
public void propertyChange(PropertyChangeEvent arg0) {
100+
try {
101+
setNewMixer((Mixer) arg0.getNewValue());
102+
} catch (Exception e) {
103+
log(e.getMessage());
104+
logger.error("Failed to select mixer.", e);
105+
}
106+
}
107+
});
108+
109+
110+
JButton clearLog = new JButton("Clear Log");
111+
clearLog.addActionListener(new ActionListener() {
112+
@Override
113+
public void actionPerformed(ActionEvent e) {
114+
logViewer.setText("");
115+
}});
116+
verboseLog.setSelected(true);
117+
118+
JPanel logControlPanel = new JPanel(new FlowLayout());
119+
logControlPanel.add(verboseLog);
120+
logControlPanel.add(clearLog);
121+
122+
JPanel containerPanel = new JPanel(new BorderLayout());
123+
JPanel centerPanel = new JPanel(new GridLayout(1, 0));
124+
centerPanel.add(inputPanel);
125+
centerPanel.add(logPanel);
126+
containerPanel.add(centerPanel, BorderLayout.CENTER);
127+
containerPanel.add(logControlPanel, BorderLayout.SOUTH);
128+
this.add(containerPanel, BorderLayout.NORTH);
129+
130+
JPanel controllerPanel = new JPanel(new GridLayout(2, 1));
131+
132+
JPanel live = new JPanel(new FlowLayout());
133+
JPanel app = new JPanel(new FlowLayout());
134+
135+
JButton login = new JButton("Login");
136+
login.addActionListener(new ActionListener() {
137+
@Override
138+
public void actionPerformed(ActionEvent e) {
139+
try {
140+
adsManager.login();
141+
} catch(Exception ie) {
142+
log(ie.getMessage());
143+
logger.error("Failed to login for API.", ie);
144+
}
145+
}});
146+
147+
JButton logout = new JButton("Logout");
148+
logout.addActionListener(new ActionListener() {
149+
@Override
150+
public void actionPerformed(ActionEvent e) {
151+
try {
152+
adsManager.logout();
153+
} catch (Exception ie) {
154+
log(ie.getMessage());
155+
logger.error("Failed to clear login credential", ie);
156+
}
157+
}});
158+
159+
JButton apply = new JButton("Apply");
160+
apply.addActionListener(new ActionListener() {
161+
@Override
162+
public void actionPerformed(ActionEvent e) {
163+
adsManager.channelId = channel.getText();
164+
adsManager.contentOwnerId = contentOwner.getText();
165+
adsManager.videoId = video.getText();
166+
try {
167+
adsManager.num = Integer.parseInt(adsNumber.getText());
168+
adsManager.duration = Long.parseLong(adsDuration.getText());
169+
} catch (Exception ie) {
170+
log(ie.getMessage());
171+
logger.error("Failed to parse parameter numbers.", ie);
172+
}
173+
}});
174+
175+
contentOwner.setToolTipText("Content Owner ID: Login to CMS and the value of 'o' parameter.");
176+
channel.setToolTipText("Channel ID starting with UC.");
177+
video.setToolTipText("Live streaming video ID.");
178+
179+
adsDuration.setText(adsManager.duration + "");
180+
adsNumber.setText(adsManager.num + "");
181+
182+
app.add(login);
183+
app.add(logout);
184+
app.add(new JLabel("Ads: Duration"));
185+
app.add(adsDuration);
186+
app.add(new JLabel("Podding"));
187+
app.add(adsNumber);
188+
189+
//app.add(clearLog);
190+
191+
live.add(new JLabel("CO"));
192+
live.add(contentOwner);
193+
live.add(new JLabel("CH"));
194+
live.add(channel);
195+
live.add(new JLabel("Video"));
196+
live.add(video);
197+
live.add(apply);
198+
199+
controllerPanel.add(app, BorderLayout.NORTH);
200+
controllerPanel.add(live, BorderLayout.SOUTH);
201+
202+
this.add(controllerPanel, BorderLayout.SOUTH);
203+
204+
JPanel otherContainer = new JPanel(new BorderLayout());
205+
otherContainer.add(panel, BorderLayout.CENTER);
206+
otherContainer.setBorder(new TitledBorder("Spectrogram"));
207+
208+
this.add(otherContainer, BorderLayout.CENTER);
209+
}
210+
211+
@Override
212+
public void log(String message) {
213+
logViewer.append(message + "\n");
214+
logViewer.setCaretPosition(logViewer.getDocument().getLength());
215+
}
216+
217+
@Override
218+
public boolean isVerbose() {
219+
return verboseLog.isSelected();
220+
}
221+
222+
private void setNewMixer(Mixer mixer) throws LineUnavailableException,
223+
UnsupportedAudioFileException {
224+
225+
if (dispatcher != null) {
226+
dispatcher.stop();
227+
}
228+
229+
final AudioFormat format = new AudioFormat(sampleRate, 16, 1, true,
230+
false);
231+
final DataLine.Info dataLineInfo = new DataLine.Info(
232+
TargetDataLine.class, format);
233+
TargetDataLine line;
234+
line = (TargetDataLine) mixer.getLine(dataLineInfo);
235+
final int numberOfSamples = bufferSize;
236+
line.open(format, numberOfSamples);
237+
line.start();
238+
final AudioInputStream stream = new AudioInputStream(line);
239+
240+
JVMAudioInputStream audioStream = new JVMAudioInputStream(stream);
241+
// create a new dispatcher
242+
dispatcher = new AudioDispatcher(audioStream, bufferSize, overlap);
243+
244+
// Mixer currentMixer = mixer;
245+
246+
// add a processor, handle pitch event.
247+
dispatcher.addAudioProcessor(new PitchProcessor(algo, sampleRate,
248+
bufferSize, this));
249+
dispatcher.addAudioProcessor(fftProcessor);
250+
251+
// run the dispatcher (on a new thread).
252+
new Thread(dispatcher, "Audio dispatching").start();
253+
}
254+
255+
AudioProcessor fftProcessor = new AudioProcessor() {
256+
257+
FFT fft = new FFT(bufferSize);
258+
float[] amplitudes = new float[bufferSize / 2];
259+
260+
@Override
261+
public void processingFinished() {
262+
// TODO Auto-generated method stub
263+
}
264+
265+
@Override
266+
public boolean process(AudioEvent audioEvent) {
267+
float[] audioFloatBuffer = audioEvent.getFloatBuffer();
268+
float[] transformbuffer = new float[bufferSize * 2];
269+
System.arraycopy(audioFloatBuffer, 0, transformbuffer, 0,
270+
audioFloatBuffer.length);
271+
fft.forwardTransform(transformbuffer);
272+
fft.modulus(transformbuffer, amplitudes);
273+
panel.drawFFT(pitch, amplitudes, fft);
274+
panel.repaint();
275+
return true;
276+
}
277+
278+
};
279+
280+
@Override
281+
public void handlePitch(PitchDetectionResult pitchDetectionResult,
282+
AudioEvent audioEvent) {
283+
if (pitchDetectionResult.isPitched()) {
284+
pitch = pitchDetectionResult.getPitch();
285+
} else {
286+
pitch = -1;
287+
}
288+
pitchHandler.handlePitch(pitchDetectionResult, audioEvent);
289+
}
290+
291+
public static void main(String... strings)
292+
throws InterruptedException, InvocationTargetException {
293+
SwingUtilities.invokeAndWait(new Runnable() {
294+
@Override
295+
public void run() {
296+
try {
297+
UIManager.setLookAndFeel(UIManager
298+
.getSystemLookAndFeelClassName());
299+
} catch (Exception e) {
300+
// ignore failure to set default look en feel;
301+
}
302+
JFrame frame = new CueApp();
303+
frame.pack();
304+
frame.setSize(640, 600);
305+
frame.setVisible(true);
306+
}
307+
});
308+
}
309+
310+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.google.api.services.samples.youtube.cmdline.partner.cuetone.audio;
2+
3+
public interface LogViewer {
4+
public void log(String message);
5+
public boolean isVerbose();
6+
}

0 commit comments

Comments
 (0)