2929using UnityEngine ;
3030using System . Collections . Generic ;
3131
32- public static class SaveWav {
32+ namespace Samples . Whisper
33+ {
34+ public static class SaveWav
35+ {
36+ private const int HeaderSize = 44 ;
3337
34- const int HEADER_SIZE = 44 ;
38+ public static byte [ ] Save ( string filename , AudioClip clip )
39+ {
40+ if ( ! filename . ToLower ( ) . EndsWith ( ".wav" ) )
41+ {
42+ filename += ".wav" ;
43+ }
3544
36- public static byte [ ] Save ( string filename , AudioClip clip ) {
37- if ( ! filename . ToLower ( ) . EndsWith ( ".wav" ) ) {
38- filename += ".wav" ;
39- }
45+ var filepath = Path . Combine ( Application . persistentDataPath , filename ) ;
4046
41- var filepath = Path . Combine ( Application . persistentDataPath , filename ) ;
47+ // Make sure directory exists if user is saving to sub dir.
48+ Directory . CreateDirectory ( Path . GetDirectoryName ( filepath ) ?? string . Empty ) ;
4249
43- // Make sure directory exists if user is saving to sub dir.
44- Directory . CreateDirectory ( Path . GetDirectoryName ( filepath ) ) ;
50+ using ( var memoryStream = CreateEmpty ( ) )
51+ {
52+ ConvertAndWrite ( memoryStream , clip ) ;
53+ WriteHeader ( memoryStream , clip ) ;
4554
46- using ( var memoryStream = CreateEmpty ( filepath ) )
47- {
48- ConvertAndWrite ( memoryStream , clip ) ;
49- WriteHeader ( memoryStream , clip ) ;
50- return memoryStream . GetBuffer ( ) ;
55+ return memoryStream . GetBuffer ( ) ;
56+ }
5157 }
52- }
53-
54- public static AudioClip TrimSilence ( AudioClip clip , float min ) {
55- var samples = new float [ clip . samples ] ;
5658
57- clip . GetData ( samples , 0 ) ;
58-
59- return TrimSilence ( new List < float > ( samples ) , min , clip . channels , clip . frequency ) ;
60- }
59+ public static AudioClip TrimSilence ( AudioClip clip , float min )
60+ {
61+ var samples = new float [ clip . samples ] ;
6162
62- public static AudioClip TrimSilence ( List < float > samples , float min , int channels , int hz ) {
63- return TrimSilence ( samples , min , channels , hz , false , false ) ;
64- }
63+ clip . GetData ( samples , 0 ) ;
6564
66- public static AudioClip TrimSilence ( List < float > samples , float min , int channels , int hz , bool _3D , bool stream ) {
67- int i ;
65+ return TrimSilence ( new List < float > ( samples ) , min , clip . channels , clip . frequency ) ;
66+ }
6867
69- for ( i = 0 ; i < samples . Count ; i ++ ) {
70- if ( Mathf . Abs ( samples [ i ] ) > min ) {
71- break ;
68+ public static AudioClip TrimSilence ( List < float > samples , float min , int channels , int hz , bool stream = false )
69+ {
70+ int i ;
71+
72+ for ( i = 0 ; i < samples . Count ; i ++ )
73+ {
74+ if ( Mathf . Abs ( samples [ i ] ) > min )
75+ {
76+ break ;
77+ }
7278 }
73- }
7479
75- samples . RemoveRange ( 0 , i ) ;
80+ samples . RemoveRange ( 0 , i ) ;
7681
77- for ( i = samples . Count - 1 ; i > 0 ; i -- ) {
78- if ( Mathf . Abs ( samples [ i ] ) > min ) {
79- break ;
82+ for ( i = samples . Count - 1 ; i > 0 ; i -- )
83+ {
84+ if ( Mathf . Abs ( samples [ i ] ) > min )
85+ {
86+ break ;
87+ }
8088 }
81- }
8289
83- samples . RemoveRange ( i , samples . Count - i ) ;
90+ samples . RemoveRange ( i , samples . Count - i ) ;
8491
85- var clip = AudioClip . Create ( "TempClip" , samples . Count , channels , hz , _3D , stream ) ;
92+ var clip = AudioClip . Create ( "TempClip" , samples . Count , channels , hz , stream ) ;
8693
87- clip . SetData ( samples . ToArray ( ) , 0 ) ;
94+ clip . SetData ( samples . ToArray ( ) , 0 ) ;
8895
89- return clip ;
90- }
96+ return clip ;
97+ }
9198
92- static MemoryStream CreateEmpty ( string filepath ) {
93- var memoryStream = new MemoryStream ( ) ;
94- byte emptyByte = new byte ( ) ;
99+ static MemoryStream CreateEmpty ( )
100+ {
101+ var memoryStream = new MemoryStream ( ) ;
102+ byte emptyByte = new byte ( ) ;
95103
96- for ( int i = 0 ; i < HEADER_SIZE ; i ++ ) //preparing the header
97- {
98- memoryStream . WriteByte ( emptyByte ) ;
99- }
104+ for ( int i = 0 ; i < HeaderSize ; i ++ ) //preparing the header
105+ {
106+ memoryStream . WriteByte ( emptyByte ) ;
107+ }
100108
101- return memoryStream ;
102- }
109+ return memoryStream ;
110+ }
103111
104- static void ConvertAndWrite ( MemoryStream memoryStream , AudioClip clip ) {
112+ static void ConvertAndWrite ( MemoryStream memoryStream , AudioClip clip )
113+ {
114+ var samples = new float [ clip . samples ] ;
105115
106- var samples = new float [ clip . samples ] ;
116+ clip . GetData ( samples , 0 ) ;
107117
108- clip . GetData ( samples , 0 ) ;
118+ Int16 [ ] intData = new Int16 [ samples . Length ] ;
119+ //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]
109120
110- Int16 [ ] intData = new Int16 [ samples . Length ] ;
111- //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]
121+ Byte [ ] bytesData = new Byte [ samples . Length * 2 ] ;
122+ //bytesData array is twice the size of
123+ //dataSource array because a float converted in Int16 is 2 bytes.
112124
113- Byte [ ] bytesData = new Byte [ samples . Length * 2 ] ;
114- //bytesData array is twice the size of
115- //dataSource array because a float converted in Int16 is 2 bytes.
125+ int rescaleFactor = 32767 ; //to convert float to Int16
116126
117- int rescaleFactor = 32767 ; //to convert float to Int16
127+ for ( int i = 0 ; i < samples . Length ; i ++ )
128+ {
129+ intData [ i ] = ( short ) ( samples [ i ] * rescaleFactor ) ;
130+ Byte [ ] byteArr = BitConverter . GetBytes ( intData [ i ] ) ;
131+ byteArr . CopyTo ( bytesData , i * 2 ) ;
132+ }
118133
119- for ( int i = 0 ; i < samples . Length ; i ++ ) {
120- intData [ i ] = ( short ) ( samples [ i ] * rescaleFactor ) ;
121- Byte [ ] byteArr = new Byte [ 2 ] ;
122- byteArr = BitConverter . GetBytes ( intData [ i ] ) ;
123- byteArr . CopyTo ( bytesData , i * 2 ) ;
134+ memoryStream . Write ( bytesData , 0 , bytesData . Length ) ;
124135 }
125136
126- memoryStream . Write ( bytesData , 0 , bytesData . Length ) ;
127- }
128-
129- static void WriteHeader ( MemoryStream memoryStream , AudioClip clip ) {
137+ static void WriteHeader ( MemoryStream memoryStream , AudioClip clip )
138+ {
130139
131- var hz = clip . frequency ;
132- var channels = clip . channels ;
133- var samples = clip . samples ;
140+ var hz = clip . frequency ;
141+ var channels = clip . channels ;
142+ var samples = clip . samples ;
134143
135- memoryStream . Seek ( 0 , SeekOrigin . Begin ) ;
144+ memoryStream . Seek ( 0 , SeekOrigin . Begin ) ;
136145
137- Byte [ ] riff = System . Text . Encoding . UTF8 . GetBytes ( "RIFF" ) ;
138- memoryStream . Write ( riff , 0 , 4 ) ;
146+ Byte [ ] riff = System . Text . Encoding . UTF8 . GetBytes ( "RIFF" ) ;
147+ memoryStream . Write ( riff , 0 , 4 ) ;
139148
140- Byte [ ] chunkSize = BitConverter . GetBytes ( memoryStream . Length - 8 ) ;
141- memoryStream . Write ( chunkSize , 0 , 4 ) ;
149+ Byte [ ] chunkSize = BitConverter . GetBytes ( memoryStream . Length - 8 ) ;
150+ memoryStream . Write ( chunkSize , 0 , 4 ) ;
142151
143- Byte [ ] wave = System . Text . Encoding . UTF8 . GetBytes ( "WAVE" ) ;
144- memoryStream . Write ( wave , 0 , 4 ) ;
152+ Byte [ ] wave = System . Text . Encoding . UTF8 . GetBytes ( "WAVE" ) ;
153+ memoryStream . Write ( wave , 0 , 4 ) ;
145154
146- Byte [ ] fmt = System . Text . Encoding . UTF8 . GetBytes ( "fmt " ) ;
147- memoryStream . Write ( fmt , 0 , 4 ) ;
155+ Byte [ ] fmt = System . Text . Encoding . UTF8 . GetBytes ( "fmt " ) ;
156+ memoryStream . Write ( fmt , 0 , 4 ) ;
148157
149- Byte [ ] subChunk1 = BitConverter . GetBytes ( 16 ) ;
150- memoryStream . Write ( subChunk1 , 0 , 4 ) ;
158+ Byte [ ] subChunk1 = BitConverter . GetBytes ( 16 ) ;
159+ memoryStream . Write ( subChunk1 , 0 , 4 ) ;
151160
152- UInt16 two = 2 ;
153- UInt16 one = 1 ;
161+ // UInt16 two = 2;
162+ UInt16 one = 1 ;
154163
155- Byte [ ] audioFormat = BitConverter . GetBytes ( one ) ;
156- memoryStream . Write ( audioFormat , 0 , 2 ) ;
164+ Byte [ ] audioFormat = BitConverter . GetBytes ( one ) ;
165+ memoryStream . Write ( audioFormat , 0 , 2 ) ;
157166
158- Byte [ ] numChannels = BitConverter . GetBytes ( channels ) ;
159- memoryStream . Write ( numChannels , 0 , 2 ) ;
167+ Byte [ ] numChannels = BitConverter . GetBytes ( channels ) ;
168+ memoryStream . Write ( numChannels , 0 , 2 ) ;
160169
161- Byte [ ] sampleRate = BitConverter . GetBytes ( hz ) ;
162- memoryStream . Write ( sampleRate , 0 , 4 ) ;
170+ Byte [ ] sampleRate = BitConverter . GetBytes ( hz ) ;
171+ memoryStream . Write ( sampleRate , 0 , 4 ) ;
163172
164- Byte [ ] byteRate = BitConverter . GetBytes ( hz * channels * 2 ) ; // sampleRate * bytesPerSample*number of channels, here 44100*2*2
165- memoryStream . Write ( byteRate , 0 , 4 ) ;
173+ Byte [ ]
174+ byteRate = BitConverter . GetBytes ( hz * channels *
175+ 2 ) ; // sampleRate * bytesPerSample*number of channels, here 44100*2*2
176+ memoryStream . Write ( byteRate , 0 , 4 ) ;
166177
167- UInt16 blockAlign = ( ushort ) ( channels * 2 ) ;
168- memoryStream . Write ( BitConverter . GetBytes ( blockAlign ) , 0 , 2 ) ;
178+ UInt16 blockAlign = ( ushort ) ( channels * 2 ) ;
179+ memoryStream . Write ( BitConverter . GetBytes ( blockAlign ) , 0 , 2 ) ;
169180
170- UInt16 bps = 16 ;
171- Byte [ ] bitsPerSample = BitConverter . GetBytes ( bps ) ;
172- memoryStream . Write ( bitsPerSample , 0 , 2 ) ;
181+ UInt16 bps = 16 ;
182+ Byte [ ] bitsPerSample = BitConverter . GetBytes ( bps ) ;
183+ memoryStream . Write ( bitsPerSample , 0 , 2 ) ;
173184
174- Byte [ ] datastring = System . Text . Encoding . UTF8 . GetBytes ( "data" ) ;
175- memoryStream . Write ( datastring , 0 , 4 ) ;
185+ Byte [ ] datastring = System . Text . Encoding . UTF8 . GetBytes ( "data" ) ;
186+ memoryStream . Write ( datastring , 0 , 4 ) ;
176187
177- Byte [ ] subChunk2 = BitConverter . GetBytes ( samples * channels * 2 ) ;
178- memoryStream . Write ( subChunk2 , 0 , 4 ) ;
188+ Byte [ ] subChunk2 = BitConverter . GetBytes ( samples * channels * 2 ) ;
189+ memoryStream . Write ( subChunk2 , 0 , 4 ) ;
179190
180- // fileStream.Close();
191+ // fileStream.Close();
192+ }
181193 }
182- }
194+ }
0 commit comments