|
Benchjoe
Posts: 13
|
 |
« on: 19 Mar '12 - 12:29 » |
Quote
|
Hi! I'm new to BASS and want to create an application for recording voice. Recorded should be in wav-files and users should be able to record-pause-continuing recording. My code works only on the first click on "record", but i'm not able to continue recording in the same file. Here it is: _Recording = true; _myRecProc = new RECORDPROC(MyRecording); _recHandle = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, _myRecProc, IntPtr.Zero); if (_enc!=null)//continue { _enc.OutputFile = "test.wav"; _enc.Start(null, IntPtr.Zero, true); _enc.Force16Bit = true; Bass.BASS_ChannelPlay(_recHandle, false); } else { _enc = new EncoderWAV(_recHandle); _enc.OutputFile = "test.wav"; _enc.Start(null, IntPtr.Zero, false); _enc.Force16Bit = true; Bass.BASS_ChannelPlay(_recHandle, true); } I can't see my mistake, am i on the wrong way? Many greetings, Joe
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15276
|
 |
« Reply #1 on: 19 Mar '12 - 15:13 » |
Quote
|
It looks like the problem there is that the WAV writer is left set on the original recording, so it won't receive data from the subsequent recordings. When using BASSenc directly, it is possible to move an encoder to another channel via the BASS_Encode_SetChannel function. When using BASS.Net's encoder classes, I believe that is done via the encoder's ChannelHandle property, something like this... if (_enc!=null)//continue { _enc.ChannelHandle = _recHandle; Bass.BASS_ChannelPlay(_recHandle, false); }
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #2 on: 21 Mar '12 - 10:43 » |
Quote
|
Hi! if (_enc!=null)//continue { _enc.ChannelHandle = _recHandle; Bass.BASS_ChannelPlay(_recHandle, false); }
Many thanks, it works. How can i play the recorded wav after pausing? I want to hear my recording, stop at a position and continue recording from this position. TIA, Joe
|
|
|
|
« Last Edit: 21 Mar '12 - 11:53 by Benchjoe »
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15276
|
 |
« Reply #3 on: 21 Mar '12 - 16:02 » |
Quote
|
How can i play the recorded wav after pausing?
You can use BASS_StreamCreateFile. Note the WAV file's header won't contain correct length information until it is updated at the end of the file writing (when the encoder is freed), so some apps may refuse to play the file before then, but BASS_StreamCreateFile should be fine with it. I want to hear my recording, stop at a position and continue recording from this position.
Do you want to continue recording at a different position in the file, not at the end of it? If so, I'm afraid that won't be possible with BASSenc, and you will need to implement the file writing yourself (write the sample data to the file in your RECORDPROC function) so that you have control over the file position. You will need to put a RIFF/WAVE header at the front of the file; examples of doing that can be found in the RECTEST and WRITEWAV examples in the BASS package.
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #4 on: 23 Mar '12 - 11:55 » |
Quote
|
Hi! Do you want to continue recording at a different position in the file, not at the end of it?
Correct! What about WaveWriter Class in Bass? Is it possible to write in wavefile from a given position? Next I need a Insert/Overwrite mode... Thx, Joe
|
|
|
|
« Last Edit: 23 Mar '12 - 13:43 by Benchjoe »
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #5 on: 9 Aug '12 - 07:36 » |
Quote
|
Hi! You will need to put a RIFF/WAVE header at the front of the file; examples of doing that can be found in the RECTEST and WRITEWAV examples in the BASS package.
Where can i find a description of the wave header like on my screenshot, which i got from wavewriter class? In detail, i need information about the shown WAVEfmt_ chunk. I want to update this header, but i get a damaged file: public void WaveHeaderReading(string spath) { FileStream fs = new FileStream(spath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs); length = (int)fs.Length - 8; fs.Position = 22; channels = br.ReadInt16(); fs.Position = 24; samplerate = br.ReadInt32(); fs.Position = 34;
BitsPerSample = br.ReadInt16(); DataLength = (int)fs.Length - 44; br.Close(); fs.Close();
}
public void WaveHeaderWriting(string sPath) { FileStream fs = new FileStream(sPath, FileMode.Open, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs); fs.Position = 0; bw.Write(new char[4] { 'R', 'I', 'F', 'F' });
bw.Write(length);
bw.Write(new char[8] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' });
bw.Write((int)16);
bw.Write((short)1); bw.Write(channels);
bw.Write(samplerate);//int32 samplerate
bw.Write((int)(samplerate * ((BitsPerSample * channels) / 8)));//byterate
bw.Write((short)((BitsPerSample * channels) / 8));//Blockalign
bw.Write((short)BitsPerSample);//bitspersample //extraparamsize 2bytes bw.Write((short)1);// //extraparams?? bw.Write(new char[4] { 'd', 'a', 't', 'a' }); bw.Write(DataLength); bw.Close(); fs.Close(); TIA, Joe
|
|
|
« Last Edit: 9 Aug '12 - 08:37 by Benchjoe »
|
Logged
|
|
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #7 on: 10 Aug '12 - 10:18 » |
Quote
|
Thank you, now i get a correct header!
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #8 on: 10 Aug '12 - 13:18 » |
Quote
|
Hi! From the position where i continued i only get silence. But why? I can't see the mistake...sorry. _myBuffer.Write(buffer, length);
byte[] ringbuffer = new byte[length]; while (true) { int i = _myBuffer.Read(buffer, length, 0); if (i > 0) { _fs.Write(ringbuffer, 0, i); } else { break; } }
Greetings, Joe
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15276
|
 |
« Reply #9 on: 13 Aug '12 - 14:13 » |
Quote
|
To confirm whether the problem is in the appending, what happens if you record to a new file instead, ie. does the file contain sound? If not, perhaps you are not recording from the device/input that you want, and the BASS_RecordInit "device" parameter needs changing? You could try playing with the pre-compiled RECTEST.EXE example from the BASS package (C\BIN folder) to confirm what devices/inputs are available and if any sound can be captured from them.
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #10 on: 17 Aug '12 - 06:49 » |
Quote
|
To confirm whether the problem is in the appending, what happens if you record to a new file instead, ie. does the file contain sound?
Yes, there is normal sound when i start recording from the beginning. Data comes into _myBuffer, now some data comes out from the position i continued the recording: LOUD, scratching NOISE. Why? RecordInit seems to work, there is no error. Thanks! Joe
|
|
|
|
« Last Edit: 23 Aug '12 - 07:22 by Benchjoe »
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #11 on: 23 Aug '12 - 07:24 » |
Quote
|
Yes, there is normal sound when i start recording from the beginning. Data comes into _myBuffer, now some data comes out from the position i continued the recording: LOUD, scratching NOISE. Why?
RecordInit seems to work, there is no error.
Thanks! Joe
Any idea from where this noise could come? TIA, Joe
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15276
|
 |
« Reply #12 on: 23 Aug '12 - 16:46 » |
Quote
|
Are you writing another WAVE header to the file? If so, you shouldn't do that. You need to update the file's existing headers instead (eg. increase the chunk lengths), and append the new sample data to the "data" chunk.
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #13 on: 24 Aug '12 - 12:02 » |
Quote
|
I use this: public void WaveHeaderReading(string spath) { FileStream fs = new FileStream(spath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs); length = (int)fs.Length - 8; fs.Position = 16; fmtlen = br.ReadInt32();
fs.Position = 22; channels = br.ReadInt16(); fs.Position = 24; samplerate = br.ReadInt32(); fs.Position = 34; BitsPerSample = br.ReadInt16(); DataLength = (int)fs.Length - 44; br.Close(); fs.Close();
}
public void WaveHeaderWriting(string sPath) { FileStream fs = new FileStream(sPath, FileMode.Open, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs); fs.Position = 0; bw.Write(new char[4] { 'R', 'I', 'F', 'F' });
bw.Write(length);
bw.Write(new char[4] { 'W', 'A', 'V', 'E'}); bw.Write(new char[4] { 'f', 'm', 't', ' ' });
bw.Write((int)fmtlen);
bw.Write((short)1); bw.Write(channels);
bw.Write(samplerate);//int32 samplerate
bw.Write((int)(samplerate * ((BitsPerSample * channels) / 8)));//byterate
bw.Write((short)((BitsPerSample * channels) / 8));//Blockalign
bw.Write((short)BitsPerSample);//bitspersample //extraparamsize 2bit bw.Write((short)1);
fs.Position = 50; bw.Write(new char[4] { 'd', 'a', 't', 'a' }); bw.Write(DataLength); bw.Close(); fs.Close(); } TIA, Joe
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #14 on: 30 Aug '12 - 09:34 » |
Quote
|
Hi! Before writing to the file i open it and jump to the end of file: _fs = new FileStream(tbFile.Text, FileMode.Append, FileAccess.Write); _fs.Seek(_fs.Length, SeekOrigin.Begin); Or should i use a Binarywriter in the CallbackMethod? Is there a difference between Filestream and Binarywriter? Greetings, Joe
|
|
|
|
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15276
|
 |
« Reply #15 on: 30 Aug '12 - 14:18 » |
Quote
|
I'm not familiar with "Filestream" or "Binarywriter", so I'm afraid I can't advise on that stuff, but the basic process would be to append the new sample data to the end of the file's existing "data" chunk, and then update the length values in the "data" and "RIFF" chunk headers to reflect the new chunk/file lengths. You wouldn't write additional chunks/headers to the file.
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #16 on: 11 Sep '12 - 12:16 » |
Quote
|
Hi!
Now i found out, that only one channel contains this loud scratching noise. The other channel contains my recordings.
Maybe a stereo/mono problem...
Greetings, Joe
|
|
|
|
« Last Edit: 11 Sep '12 - 13:27 by Benchjoe »
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #17 on: 11 Sep '12 - 13:33 » |
Quote
|
The difference between a .Net 'FileStream' and 'BinrayWriter' is e.g. explained here: http://forums.asp.net/t/1767499.aspx/1Bass.Net uses in the WaveWriter class a BinaryWriter with a FileStream, basically like this: FileStream fs = new FileStream(<FileName>, FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); ... bw.Write(...)
As Ian indicated, you can not simply append new sample data to an existing .wav file, as the sample data must be appended inside the "data" chunk of the wave file, plus the "RIFF" header chunk must be updated to reflect the new data chunk length. A detailed wave format description can be e.g. found here: http://tools.ietf.org/html/draft-ema-vpim-wav-00
|
|
|
|
|
Logged
|
|
|
|
|
Benchjoe
Posts: 13
|
 |
« Reply #18 on: 11 Sep '12 - 14:41 » |
Quote
|
Hi Bernd! As Ian indicated, you can not simply append new sample data to an existing .wav file, as the sample data must be appended inside the "data" chunk of the wave file, plus the "RIFF" header chunk must be updated to reflect the new data chunk length. A detailed wave format description can be e.g. found here: http://tools.ietf.org/html/draft-ema-vpim-wav-00Thx, i tested Binarywriter vs. Filestream. With the same result. I thought, that i have done this als Ian indicated. If the 'data' chunk is the last chunk in the file, i can append the sample data and update the headers. Greetings, Joe
|
|
|
|
|
Logged
|
|
|
|
|
saga
Posts: 1365
|
 |
« Reply #19 on: 11 Sep '12 - 14:51 » |
Quote
|
Actually, a WAV file may contain several data chunks, but software behaviour will probably differ largely wrt to this feature (most software will just read the first chunk).
|
|
|
|
|
Logged
|
|
|
|
|