1111import javax .sound .sampled .DataLine ;
1212import javax .sound .sampled .LineUnavailableException ;
1313import javax .sound .sampled .TargetDataLine ;
14- import java .io .ByteArrayOutputStream ;
14+ import javax .swing .JFrame ;
15+ import javax .swing .WindowConstants ;
16+ import java .awt .event .WindowAdapter ;
17+ import java .awt .event .WindowEvent ;
1518import java .util .Arrays ;
19+ import java .util .concurrent .atomic .AtomicBoolean ;
1620
1721/**
1822 * Application that shows real-time spectrum of sound
@@ -28,45 +32,58 @@ public static void main(String[] args) throws LineUnavailableException {
2832 AudioFormat audioFormat = buildAudioFormat ();
2933 DataLine .Info dataLineInfo = new DataLine .Info (TargetDataLine .class , audioFormat );
3034
31- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ();
3235 TargetDataLine targetDataLine = (TargetDataLine ) AudioSystem .getLine (dataLineInfo );
3336 targetDataLine .open (audioFormat );
3437
3538 ChartContainer chartContainer = new ChartContainer ();
36- chartContainer .show ();
39+ JFrame chartFrame = chartContainer .show ();
40+ chartFrame .setDefaultCloseOperation (WindowConstants .EXIT_ON_CLOSE );
41+
42+ AtomicBoolean capturing = new AtomicBoolean (true );
43+ chartFrame .addWindowListener (new WindowAdapter () {
44+ @ Override
45+ public void windowClosing (WindowEvent e ) {
46+ capturing .set (false );
47+ targetDataLine .stop ();
48+ }
49+ });
3750
3851 byte tempBuffer [] = new byte [10_000 ];
3952 double [] xData = new double [BUCKETS_AMOUNT ];
4053 double [] yData = new double [BUCKETS_AMOUNT ];
41- while (true ) {
42- targetDataLine .start ();
43- int count = targetDataLine .read (tempBuffer , 0 , tempBuffer .length );
44- if (count > 0 ) {
45- byteArrayOutputStream .write (tempBuffer , 0 , count );
46- }
47- byte audioData [] = byteArrayOutputStream .toByteArray ();
48- targetDataLine .stop ();
49- byteArrayOutputStream .reset ();
50-
51- FrequencyInfoContainer frequencyInfoContainer = frequencyScanner .detectFrequency (audioData , (int ) audioFormat .getSampleRate ());
52- double [] frequencies = frequencyInfoContainer .frequencies ();
53- double [] magnitudes = frequencyInfoContainer .magnitudes ();
54-
55- Arrays .fill (xData , 0 );
56- Arrays .fill (yData , 0 );
57- final int magnitudesPerBucket = magnitudes .length / BUCKETS_AMOUNT ;
58- for (int bucket = 0 ; bucket < BUCKETS_AMOUNT ; bucket ++) {
59- xData [bucket ] = frequencies [(int ) ((bucket + 0.5 ) * magnitudesPerBucket )];
60-
61- for (int i = 0 ; i < magnitudesPerBucket ; i ++) {
62- yData [bucket ] += magnitudes [bucket * magnitudesPerBucket + i ];
54+ targetDataLine .start ();
55+ try {
56+ while (capturing .get ()) {
57+ int count = targetDataLine .read (tempBuffer , 0 , tempBuffer .length );
58+ if (count <= 0 ) {
59+ continue ;
60+ }
61+ byte [] audioData = Arrays .copyOf (tempBuffer , count );
62+
63+ FrequencyInfoContainer frequencyInfoContainer =
64+ frequencyScanner .detectFrequency (audioData , (int ) audioFormat .getSampleRate ());
65+ double [] frequencies = frequencyInfoContainer .frequencies ();
66+ double [] magnitudes = frequencyInfoContainer .magnitudes ();
67+
68+ Arrays .fill (xData , 0 );
69+ Arrays .fill (yData , 0 );
70+ final int magnitudesPerBucket = magnitudes .length / BUCKETS_AMOUNT ;
71+ for (int bucket = 0 ; bucket < BUCKETS_AMOUNT ; bucket ++) {
72+ xData [bucket ] = frequencies [(int ) ((bucket + 0.5 ) * magnitudesPerBucket )];
73+
74+ for (int i = 0 ; i < magnitudesPerBucket ; i ++) {
75+ yData [bucket ] += magnitudes [bucket * magnitudesPerBucket + i ];
76+ }
6377 }
64- }
6578
66- var maxFrequency = frequencyInfoContainer .maxFrequency ();
67- String title = String .format ("%1$.0f Hz" , maxFrequency );
79+ var maxFrequency = frequencyInfoContainer .maxFrequency ();
80+ String title = String .format ("%1$.0f Hz" , maxFrequency );
6881
69- chartContainer .update (xData , yData , title );
82+ chartContainer .update (xData , yData , title );
83+ }
84+ } finally {
85+ targetDataLine .stop ();
86+ targetDataLine .close ();
7087 }
7188 }
7289
@@ -85,9 +102,9 @@ public ChartContainer() {
85102 chart .getStyler ().setXAxisLogarithmic (true );
86103 }
87104
88- public void show () {
105+ public JFrame show () {
89106 chartSwingWrapper = new SwingWrapper <>(chart );
90- chartSwingWrapper .displayChart ();
107+ return chartSwingWrapper .displayChart ();
91108 }
92109
93110 public void update (double [] xData , double [] yData , String title ) {
0 commit comments