First I opened from the smart media card a fresh recorded sample loop with an hex editor
and found out it's a simple Zoom TEXT header and a 32bit fixed Zoom ID aligned to 512 bytes (filled with zeros)
Then I loaded with the open source editor 'Audacity' the the Zoom sample *.BIN file as raw mono 16bit 44.1KHz audio file as big endian (skiping the first 512 bytes header)
While playback it was to fast so I read the *.pdf manual and found out the sample engine sampled with 31.25KHz ! (not bad in the 90th)
In Audacity you can change the playback rate of an audio track to 31250 Hz and the playback speed was OK now.
The problem are you can import WAV, MP3, RAW etc. files in Audacity but you can't export it as raw file with new sample rate nor in big endian !
Long story short I wrote this tiny Mono/Stero 8/16 bit '*.WAV' file converter to create Zoom 16 bit Mono 31.25KHz *.BIN files.
(the wav import is the same stuff used in FBSound)
I import any stuff in Audacity and save it as "SAMPLE00.wav ... SAMPLE99.wav"
then I drag and drob this created wav files over the tool wav2sample.exe the result are "SAMPLE00.BIN ... SAMPLE99.bin"
(other file names are ignored from smart media card)
On linux I must give a filename manualy e.g.: /wav2sample sample12.wav
There is one tiny pitfall a "1" on red seven segment display in the sampler menu means the "sample00.bin" a "2" "sample01.bin" ...
Joshy
file: "wav2sample.bas"
Code: Select all
#ifndef NULL
#define NULL cptr(any ptr,0)
#endif
const _WAVE_FORMAT_PCM as short = 1
const _PCM_WAVEFORMAT_SIZE as long = 16
const _PCM_FMT_SIZE as long = 16
const _PCM_FILE_HDR_SIZE = 44
type VCCs as ulong
const as VCCs _RIFF = &H46464952 ' 'RIFF'
const as VCCs _WAVE = &H45564157 ' 'WAVE'
const as VCCs _fmt = &H20746D66 ' 'fmt '
const as VCCs _data = &H61746164 ' 'data'
type _PCM_FILE_HDR field = 1
ChunkRIFF as VCCs ' 00-03 'RIFF'
ChunkRIFFSize as long ' 04-07 (maximal: filesize-8)
ChunkID as VCCs ' 08-11 'WAVE'
ChunkFMT as VCCs ' 12-15 'fmt '
ChunkFMTSize as long ' 16-19 (16)
wFormatTag as short ' 20-21 (1 (uncompresses) _PCM_FMT_SIZE)
nChannels as short ' 22-23 (1|2...)
nRate as long ' 24-27 ( ... 10025,22050,44100 ...)
nBytesPerSec as long ' 28-31 (nRate*Framesize)
Framesize as short ' 32-33 (nChannels*(nBits\8)
nBits as short ' 34-35 (8,16, ...)
ChunkDATA as VCCs ' 36-39 'data'
ChunkDATASize as long ' 40-43 (maximal: filesize-44)
end type
' fill wave header struct
' return in DataPos the file position of the first sample.
private _
function GetWaveInfo(byval FileName as string , _
byref Hdr as _PCM_FILE_HDR , _
byref DataPos as integer) as boolean
Dim as integer FileSize, filePos
var hFile = FreeFile()
if open(FileName for binary access read As #hFile)=0 then
FileSize = lof(hFile)
if FileSize > _PCM_FILE_HDR_SIZE then
get #hFile,, Hdr.ChunkRIFF
if Hdr.ChunkRIFF = _RIFF then
get #hFile,, Hdr.ChunkRIFFSize
get #hFile,, Hdr.ChunkID
if Hdr.ChunkID = _WAVE then
filePos = seek(hFile)
' search for "fmt " chunk skip any other chunks
Hdr.Chunkfmt=0
while (Hdr.Chunkfmt <> _fmt) and (eof(hFile) = 0)
get #hFile, filePos, Hdr.Chunkfmt : filePos += 1
wend
if Hdr.Chunkfmt = _fmt then
get #hFile,,Hdr.ChunkfmtSize
if Hdr.ChunkfmtSize >= _PCM_FMT_SIZE then
get #hFile,,Hdr.wFormattag
if Hdr.wFormattag = _WAVE_FORMAT_PCM then
get #hFile,,Hdr.nChannels
get #hFile,,Hdr.nRate
get #hFile,,Hdr.nBytesPerSec
get #hFile,,Hdr.Framesize
get #hFile,,Hdr.nBits
filePos = seek(hFile)
' search for "data" chunk skip any other chunks
Hdr.Chunkdata=0
while (Hdr.Chunkdata <> _data) and (eof(hFile) = 0)
get #hFile, filePos, Hdr.Chunkdata : filePos += 1
wend
if Hdr.Chunkdata = _data Then
get #hFile,,Hdr.ChunkdataSize
if Hdr.ChunkdataSize > 0 and eof(hFile) = 0 Then
filePos = seek(hFile)
close #hFile
DataPos = filePos
return true
end if ' Chunkdatasize>0
end if ' Chunkdata=_data
end if ' wFormattag = WAVE_FORMAT_PCM
end if ' ChunkfmtSize >= PCM_FMT_SIZE
end if ' Chunkfmt = _fmt
end if ' ChunkID = _WAVE
end if ' ChunkRIFF = _RIFF
end if ' FileSize > PCM_FILE_HDR_SIZE
close #hFile
end if ' open=0
return false
end function
' load samples from *.wav file
' convert from stereo<->mono or wise versa
' convert from 8->16 bits (if needed)
' return in nBytesLoaded loaded/converted bytes
private _
function Load16BitWave(byval Filename as string, _
byval nRateTarget as integer, _
byval nChannelsTarget as integer, _
byref nBytesLoaded as integer) as any ptr
const as integer nBitsTarget=16
dim as _PCM_FILE_HDR hdr
dim as integer SeekPos,nBytesTarget,nSamples,nSamplesTarget,i,oPos,cPos
dim as single l,r
dim as double Scale,nPos
dim as ubyte v8
dim as short v16
dim as short ptr p16
if nChannelsTarget<1 then
nChannelsTarget=1
elseif nChannelsTarget>1 then
nChannelsTarget=2
endif
oPos=-1
if GetWaveInfo(Filename,hdr,SeekPos)=true then
nSamples = hdr.ChunkDataSize \ hdr.FrameSize
Scale = hdr.nRate/nRateTarget
nSamplesTarget = nSamples*(1.0/Scale)
nBytesTarget = nSamplesTarget*(nBitsTarget\8)*nChannelsTarget
var hFile = Freefile()
if open(FileName for binary access read as #hFile)=0 then
seek #hFile,SeekPos
p16 = callocate(nBytesTarget)
if (p16 = NULL) then
print "error: _LoadWave() out of memeory !"
close #hFile : return NULL
end if
if nSamples<=nSamplesTarget then
for i=0 to nSamplesTarget-1
' jump over in source
if oPos<>cPos then
' read samples l,r -0.5 - 0.5
if hdr.nBits=8 then
'read ubyte 0<->255
get #hFile,,v8
' convert to -128.0 <-> +127.0
l=csng(v8):l-=128
' convert to -0.5 <-> +0.5
l*=(0.5f/128.0f)
if hdr.nChannels=2 then
get #hFile,,v8
r=csng(v8):r-=128
' convert to -0.5 <-> +0.5
r*=(0.5f/128.0f)
else
r = l ' mono left channel = right channel
end if
else ' 16 bits
get #hFile,,v16 : l=(0.5f/32767.0f)*v16
if hdr.nChannels=2 then
get #hFile,,v16 : r=(0.5f/32767.0f)*v16
else
r = l ' mono left channel = right channel
end if
end if
oPos=cPos
end if
' write every in target
if nChannelsTarget=1 then
p16[i ]=cshort(l*16383f + r*16383f)
else
p16[i*2 ]=cshort(l*32767.0f)
p16[i*2+1]=cshort(r*32767.0f)
end if
nPos+=scale : cPos=int(nPos)
' don't read more than len(source)
if cPos>=nSamples then exit for
next
else ' read every source Sample
scale=(1.0/scale)
for i=0 to nSamples-1
' read samples l,r -0.5 - +0.5
if hdr.nBits=8 then
'read ubyte 0<->255
get #hFile,,v8
' convert to -128.0 <-> +127.0
l=csng(v8):l-=128
' convert to -0.5 <-> +0.5
l*=(0.5f/128.0f)
if hdr.nChannels=2 then
get #hFile,,v8
r=csng(v8):r-=128
' convert to -0.5 <-> +0.5
r*=(0.5f/128.0f)
else
r=l ' mono left channel = right channel
end if
else
get #hFile,,v16:l=(0.5f/32767.0f)*v16
if hdr.nChannels=2 then
get #hFile,,v16:r=(0.5f/32767.0f)*v16
else
r=l ' mono left channel = right channel
end if
end if
' jump over in destination
if oPos<>cPos then
if nChannelsTarget=1 then
p16[cPos ]=cshort(l*16383.5f + r*16383.5f)
else
p16[cPos*2 ]=cshort(l*32767.0f)
p16[cPos*2+1]=cshort(r*32767.0f)
end if
oPos=cPos
end if
nPos+=scale:cPos=int(nPos)
' don't write more than len(target)
if cPos >= (nSamplesTarget-1) then exit for
next
end if
close #hFile
nBytesLoaded = nBytesTarget
return p16
end if ' open()=0
end if ' GetWaveInfo()=true
return NULL
end function
type ZOOM_SAMPLE_HEADER ' 48 bytes
declare constructor
as zstring * 44 ID ' 43 chars + 1 NULL = 44
as ulong u32 ' &HF62E1D = 16133661
as ubyte empty(463) ' 464 bytes + 48 bytes = !!! 512 !!!
end type
constructor ZOOM_SAMPLE_HEADER
ID = "ZOOM 707-2 SAMPLE DATA VER0001 "
u32 = &HF62E1D
end constructor
' get *.wav file from command line
var wavFile = command(1)
chdir exepath()
if open(wavFile,for binary,access read, as 1) then
print "can't read '" & wavFile & "' !"
beep : sleep : end 1
endif
close 1
' load and convert wav file to 16bit mono raw data
dim as integer nBytes
dim as ubyte ptr pBytes = Load16BitWave(wavFile,31250,1,nBytes)
if pBytes=NULL then
print "can't convert '" & wavFile & "' !"
beep : sleep : end 1
end if
' convert LE 16bit to BE 16bit mono channel
for i as integer = 0 to nBytes-1 step 2
swap pBytes[i],pBytes[i+1]
next
' write ZOOM 707II sample file
dim as ZOOM_SAMPLE_HEADER smpHeader
var smpFile = left(wavFile,len(wavFile)-4) & ".BIN"
if open(smpFile,for binary,access write, as 1) then
print "can't write '" & smpFile & "' !"
beep : sleep : end 0
endif
' write ZOOM 707II header (512 bytes)
put #1,,smpHeader
' write ZOOM 707II 16bit mono samples with 31.25KHz (big endians)
put #1,,*pBytes,nBytes
close 1
print "wrote " & nBytes & " in '" & smpFile & "'"
deallocate pBytes
print "ok"