1+ package com .baeldung .example .soundapi ;
2+
3+ import java .io .ByteArrayInputStream ;
4+ import java .io .ByteArrayOutputStream ;
5+ import java .io .IOException ;
6+ import javax .sound .sampled .AudioFormat ;
7+ import javax .sound .sampled .AudioInputStream ;
8+ import javax .sound .sampled .AudioSystem ;
9+ import javax .sound .sampled .DataLine ;
10+ import javax .sound .sampled .TargetDataLine ;
11+
12+ public class SoundRecorder implements Runnable {
13+ private AudioInputStream audioInputStream ;
14+ private AudioFormat format ;
15+ public Thread thread ;
16+ private double duration ;
17+
18+ public SoundRecorder () {
19+ super ();
20+ }
21+
22+ public SoundRecorder (AudioFormat format ) {
23+ this .format = format ;
24+ }
25+
26+ public SoundRecorder build (AudioFormat format ) {
27+ this .format = format ;
28+ return this ;
29+ }
30+
31+ public void start () {
32+ thread = new Thread (this );
33+ thread .setName ("Capture Microphone" );
34+ thread .start ();
35+ }
36+
37+ public void stop () {
38+ thread = null ;
39+ }
40+
41+ @ Override
42+ public void run () {
43+ duration = 0 ;
44+
45+ try (final ByteArrayOutputStream out = new ByteArrayOutputStream (); final TargetDataLine line = getTargetDataLineForRecord ();) {
46+
47+ int frameSizeInBytes = format .getFrameSize ();
48+ int bufferLengthInFrames = line .getBufferSize () / 8 ;
49+ final int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes ;
50+ buildByteOutputStream (out , line , frameSizeInBytes , bufferLengthInBytes );
51+ this .audioInputStream = new AudioInputStream (line );
52+ setAudioInputStream (convertToAudioIStream (out , frameSizeInBytes ));
53+ audioInputStream .reset ();
54+ } catch (IOException ex ) {
55+ ex .printStackTrace ();
56+ } catch (Exception ex ) {
57+ ex .printStackTrace ();
58+ return ;
59+ }
60+ }
61+
62+ public void buildByteOutputStream (final ByteArrayOutputStream out , final TargetDataLine line , int frameSizeInBytes , final int bufferLengthInBytes ) throws IOException {
63+ final byte [] data = new byte [bufferLengthInBytes ];
64+ int numBytesRead ;
65+
66+ line .start ();
67+ while (thread != null ) {
68+ if ((numBytesRead = line .read (data , 0 , bufferLengthInBytes )) == -1 ) {
69+ break ;
70+ }
71+ out .write (data , 0 , numBytesRead );
72+ }
73+ }
74+
75+ private void setAudioInputStream (AudioInputStream aStream ) {
76+ this .audioInputStream = aStream ;
77+ }
78+
79+ public AudioInputStream convertToAudioIStream (final ByteArrayOutputStream out , int frameSizeInBytes ) {
80+ byte audioBytes [] = out .toByteArray ();
81+ ByteArrayInputStream bais = new ByteArrayInputStream (audioBytes );
82+ AudioInputStream audioStream = new AudioInputStream (bais , format , audioBytes .length / frameSizeInBytes );
83+ long milliseconds = (long ) ((audioInputStream .getFrameLength () * 1000 ) / format .getFrameRate ());
84+ duration = milliseconds / 1000.0 ;
85+ System .out .println ("Recorded duration in seconds:" + duration );
86+ return audioStream ;
87+ }
88+
89+ public TargetDataLine getTargetDataLineForRecord () {
90+ TargetDataLine line ;
91+ DataLine .Info info = new DataLine .Info (TargetDataLine .class , format );
92+ if (!AudioSystem .isLineSupported (info )) {
93+ return null ;
94+ }
95+ try {
96+ line = (TargetDataLine ) AudioSystem .getLine (info );
97+ line .open (format , line .getBufferSize ());
98+ } catch (final Exception ex ) {
99+ return null ;
100+ }
101+ return line ;
102+ }
103+
104+ public AudioInputStream getAudioInputStream () {
105+ return audioInputStream ;
106+ }
107+
108+ public AudioFormat getFormat () {
109+ return format ;
110+ }
111+
112+ public void setFormat (AudioFormat format ) {
113+ this .format = format ;
114+ }
115+
116+ public Thread getThread () {
117+ return thread ;
118+ }
119+
120+ public double getDuration () {
121+ return duration ;
122+ }
123+ }
0 commit comments