ページ 1 / 1
BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 21:51
by Ciel
しょうもない質問ですみません。
たとえば、
BYTE *byte=(BYTE*)malloc(1000);
ていうふうにBYTE型のメモリを動的確保したとして、その領域にデーターを書き込んだとします。
これを符号ありのsigned short型に変換したいんですが、正しい方法を教えて下さい。
signed short *s=(signed short*)malloc(1000);
memcpy(byte,s,1000);
とか,
signed short *s=(signed short*)byte;
とか、やってみたんですが、どうもデータが符号ありに書き換わっていないようです。
何で変なことしてるのかというと、録音した音声データをwaveファイルにするための書き出しを行っているんですが、
メモリに記録する際は符号なしで記録しているのに対し、16ビットのwaveデータの場合、
符号ありでファイルに書き出さなければならないようなので、変換する必要が出てきたためです。
どなたかわかる方、ご回答よろしくお願いします。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 21:54
by kimuchi
符号なしはunsignedではないでしょうか?
間違ってたら済みません。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 21:55
by box
BYTEというのがどういう型なのかわからないので、
何ともお答えしようがありません。
ご自分で定義された型ですか?
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 21:57
by Ciel
文章に一部間違いがあったので訂正しました。
符号「あり」に変換したいのです。
>>boxさん
BYTE型はunsigned char型です。windows.hかどこかのヘッダで定義されています。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 22:23
by h2so5
符号ありへの変換という意味がよく分からないのですが、
signed short s=(signed short)*byte;
このような変換のことを言っているのでしょうか。
Ciel さんの書かれている、
signed short *s=(signed short*)byte;
ですと、
unsigned char型のポインタをデータサイズの違うsigned shortのポインタに変換しているので、
データが壊れてしまうと思いますが。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 22:34
by Ciel
ちょっと根本から考え直してみますので、しばらく放置しといて構いません。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 22:38
by kimuchi
ポインタの型変換自体は問題ないと思います。
それより、型変換をしたところで内部データは変わらないと思うのですが...
読み込みならまだしも、書き込みで型変換が必要なのでしょうか?
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月04日(火) 23:43
by softya(ソフト屋)
そもそも確保されたメモリに8bit符合なしで記録されているのか、16bit符号無しで記録されているのか話が変わります。これが明確にして欲しい事です。
それと符号付きに変換するには、1サンプリングづつ変換するしか無いのでforループで回すしか有りません。
castとかそういう問題ではないと思いますよ。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月05日(水) 07:22
by Ciel
>>softyaさん。
そこです。
私が正に気にしているところは8bit符号なしで記録されているのかが分からなくなっています。
今ちょっとどう記録されているのかが分からない状態でして、色々調べています。
録音時に使用するWAVEHDR構造体のlpdataメンバがその記録するときに使うバッファなのですが、
型はLPSTRなのでchar型のポインタなんですよね。
でも16ビットで記録するということは2バイト使ってるはずなんですが、メモリ自体はBYTE型の1バイト単位で確保
しているので、その状態で記録したら符号ありなのかなしなのかどういう状態で記録されているのかが、
わからないんですよね。
>それと符号付きに変換するには、1サンプリングづつ変換するしか無いのでforループで回すしか有りません。
castとかそういう問題ではないと思いますよ。
この発言のとおり、やっぱりそうじゃないかなと思い始めてたところでした。
一度最初からsinged short型で動的確保してやってみて、もしダメなら一つずつ変換していこうかと思います。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月05日(水) 10:59
by softya(ソフト屋)
waveInOpenを使っているんですよね?
であれば、wBitsPerSampleで指定したビット数で記録されていると思います。
記録する側でバッファの型なんてのはキャストすれば良いのでLPSTRであることは8bit記録の証拠にはなりません。
>メモリ自体はBYTE型の1バイト単位で確保
メモリに型なんてものはありません。
メモリを指しているポインタの型は、実際にメモリに書かれているデータの型を保証するものではありませんよ。
例えば
(signed short*)malloc(1000);
と書いたとしても、mallocでは型を決めているわけではないですよね。
malloc(1000);とサイズを指定しただけです。
(signed short*)でキャストしてますが、これはポインタの型を変えているだけでメモリの中身なんか知ったことではありません。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月05日(水) 18:24
by Ciel
softyaさんありがとうございます。
なんとなくメモリに型なんてないよなぁとは思っていたんですが、まだ良くわかっていませんでした。
8ビットと16ビットの違いは下記の通りです。
・8bit ならば符号無し unsigned (0 ~ 255, 無音は 128)
・16bit ならば符号付き signed (-32768 ~ +32767, 無音は 0)
wBitsPerSampleを16ビットに設定して、waveInStartで録音した場合、この符号付きの値で記録できていると思っていいのでしょうか?
実際16ビットにして記録すると、綺麗な音声になるので16ビットでは記録できていると思われるのですが。。。
その記録したバッファをwaveOutWriteで再生すると問題なく綺麗な音で再生できます。
ですが、そのバッファを下記のようにwaveファイルとして書き出そうとすると、コピーガードがかかったような
とても聞き取れないようなバリバリッとした音しか記録されません。
ですが、8ビットに設定して記録すると、下のコードでも正しくwaveファイルは作成できます。
16ビットで録音したときの、正しいwaveファイルの作成方法が分かればご回答お願いします。
コード:
//savedataがバッファ、bufsizeがそのサイズ
fp=fopen(buf3,"w");
fputs("RIFF",fp);
//WAVE,fmt,fmtsize,data,datasize+waveformatex+波形データサイズ書き込み。
wr=bufsize+sizeof(WAVEFORMATEX)+20;
fwrite(&wr,sizeof(wr),1,fp);
fputs("WAVE",fp);
fputs("fmt ",fp);
wr=sizeof(WAVEFORMATEX);
fwrite(&wr,sizeof(wr),1,fp);
fwrite(&wf,sizeof(wf),1,fp);
fputs("data",fp);
wr=bufsize;
fwrite(&wr,sizeof(wr),1,fp);
fwrite(savedata,bufsize,1,fp);
fclose(fp);
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月06日(木) 01:03
by kimuchi
fopenのところは”w”ではなく”wb”ではないですか?
先日からなんだかでしゃばってすみません˃˂
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月06日(木) 01:19
by Ciel
>>kimuchiさん
いえいえ、回答いただけるだけですごい嬉しいです。
で、ご指摘の通りです。
何でバイナリで書き込んでるのにテキストモードにしてたのだろうか。。。
ちょっとバイナリモードにしてやってみますね!
ありがとうございます!
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月06日(木) 01:31
by Ciel
うわあwwバイナリモードにしたらいけましたw
バイナリで書き込んでるのにテキストモードじゃダメですよねw
まったく信じられないミスしてましたw
何で気づかなかったんだろう?w
テキストモードとバイナリモードは改行の扱いの違いぐらいしかないけど、
16ビットの波形データの中に改行コードと同じコードが含まれていたんでしょうね。。。
本当に何でバイナリモードにしてなかったのか、自分でも信じられない。。
穴があったら入りたいです。。
タイトルとか全然関係ないタイトルだしw恥ずかしくてしょうがないw
softyaさん、私の完全な凡ミスに付き合せてしまったようで、本当に申し訳ございませんでした。
メモリのことについてはお勉強になりました。ありがとうございました。
kimuchiさん、本当に助かりました!
たぶん指摘していただけなかったら、ずっと気づかなかったとおもいますw
色々とググってたのがバカみたいです。。。
もっと視野を広く持たなきゃだめですね!
皆さんご迷惑をおかけ致しまして、申し訳ございませんでした。
本当にありがとうございました。これからもよろしくお願い致します!
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月06日(木) 10:47
by softya(ソフト屋)
すいません、昨日は風邪でだうんしてました。
無事解決して良かったです。
気をつけるとしたら、バイナリエディタでみるとかWAVファイルの波形を可視化するツールで一度チェックしていれば気づいたかも知れませんね。
Re: BYTE型からsigned short型への正しい変換
Posted: 2011年1月06日(木) 19:16
by Ciel
>>softyaさん
そうですね。波形を見たら気づいたかもしれませんね。
今後同じようなことがあったら一回波形見てみますね。ありがとうございました。