BYTE型からsigned short型への正しい変換

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
Ciel
記事: 252
登録日時: 9年前

BYTE型からsigned short型への正しい変換

#1

投稿記事 by Ciel » 9年前

しょうもない質問ですみません。

たとえば、
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データの場合、
符号ありでファイルに書き出さなければならないようなので、変換する必要が出てきたためです。

どなたかわかる方、ご回答よろしくお願いします。
最後に編集したユーザー Ciel on 2011年1月04日(火) 21:55 [ 編集 1 回目 ]
oui C'est la Vie♪

アバター
kimuchi
記事: 163
登録日時: 9年前
住所: 東京

Re: BYTE型からsigned short型への正しい変換

#2

投稿記事 by kimuchi » 9年前

符号なしはunsignedではないでしょうか?
間違ってたら済みません。

box
記事: 1745
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#3

投稿記事 by box » 9年前

BYTEというのがどういう型なのかわからないので、
何ともお答えしようがありません。

ご自分で定義された型ですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#4

投稿記事 by Ciel » 9年前

文章に一部間違いがあったので訂正しました。

符号「あり」に変換したいのです。

>>boxさん
BYTE型はunsigned char型です。windows.hかどこかのヘッダで定義されています。
oui C'est la Vie♪

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: BYTE型からsigned short型への正しい変換

#5

投稿記事 by h2so5 » 9年前

符号ありへの変換という意味がよく分からないのですが、
signed short s=(signed short)*byte;
このような変換のことを言っているのでしょうか。

Ciel さんの書かれている、
signed short *s=(signed short*)byte;
ですと、
unsigned char型のポインタをデータサイズの違うsigned shortのポインタに変換しているので、
データが壊れてしまうと思いますが。

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#6

投稿記事 by Ciel » 9年前

ちょっと根本から考え直してみますので、しばらく放置しといて構いません。
oui C'est la Vie♪

アバター
kimuchi
記事: 163
登録日時: 9年前
住所: 東京

Re: BYTE型からsigned short型への正しい変換

#7

投稿記事 by kimuchi » 9年前

ポインタの型変換自体は問題ないと思います。
それより、型変換をしたところで内部データは変わらないと思うのですが...
読み込みならまだしも、書き込みで型変換が必要なのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: BYTE型からsigned short型への正しい変換

#8

投稿記事 by softya(ソフト屋) » 9年前

そもそも確保されたメモリに8bit符合なしで記録されているのか、16bit符号無しで記録されているのか話が変わります。これが明確にして欲しい事です。
それと符号付きに変換するには、1サンプリングづつ変換するしか無いのでforループで回すしか有りません。
castとかそういう問題ではないと思いますよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#9

投稿記事 by Ciel » 9年前

>>softyaさん。
そこです。
私が正に気にしているところは8bit符号なしで記録されているのかが分からなくなっています。
今ちょっとどう記録されているのかが分からない状態でして、色々調べています。
録音時に使用するWAVEHDR構造体のlpdataメンバがその記録するときに使うバッファなのですが、
型はLPSTRなのでchar型のポインタなんですよね。

でも16ビットで記録するということは2バイト使ってるはずなんですが、メモリ自体はBYTE型の1バイト単位で確保
しているので、その状態で記録したら符号ありなのかなしなのかどういう状態で記録されているのかが、
わからないんですよね。

>それと符号付きに変換するには、1サンプリングづつ変換するしか無いのでforループで回すしか有りません。
castとかそういう問題ではないと思いますよ。

この発言のとおり、やっぱりそうじゃないかなと思い始めてたところでした。
一度最初からsinged short型で動的確保してやってみて、もしダメなら一つずつ変換していこうかと思います。
oui C'est la Vie♪

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: BYTE型からsigned short型への正しい変換

#10

投稿記事 by softya(ソフト屋) » 9年前

waveInOpenを使っているんですよね?
であれば、wBitsPerSampleで指定したビット数で記録されていると思います。
記録する側でバッファの型なんてのはキャストすれば良いのでLPSTRであることは8bit記録の証拠にはなりません。

>メモリ自体はBYTE型の1バイト単位で確保

メモリに型なんてものはありません。
メモリを指しているポインタの型は、実際にメモリに書かれているデータの型を保証するものではありませんよ。

例えば
(signed short*)malloc(1000);
と書いたとしても、mallocでは型を決めているわけではないですよね。
malloc(1000);とサイズを指定しただけです。
(signed short*)でキャストしてますが、これはポインタの型を変えているだけでメモリの中身なんか知ったことではありません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#11

投稿記事 by Ciel » 9年前

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);
oui C'est la Vie♪

アバター
kimuchi
記事: 163
登録日時: 9年前
住所: 東京

Re: BYTE型からsigned short型への正しい変換

#12

投稿記事 by kimuchi » 9年前

fopenのところは”w”ではなく”wb”ではないですか?
先日からなんだかでしゃばってすみません˃˂

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#13

投稿記事 by Ciel » 9年前

>>kimuchiさん
いえいえ、回答いただけるだけですごい嬉しいです。

で、ご指摘の通りです。
何でバイナリで書き込んでるのにテキストモードにしてたのだろうか。。。
ちょっとバイナリモードにしてやってみますね!

ありがとうございます!
oui C'est la Vie♪

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#14

投稿記事 by Ciel » 9年前

うわあwwバイナリモードにしたらいけましたw

バイナリで書き込んでるのにテキストモードじゃダメですよねw
まったく信じられないミスしてましたw
何で気づかなかったんだろう?w

テキストモードとバイナリモードは改行の扱いの違いぐらいしかないけど、
16ビットの波形データの中に改行コードと同じコードが含まれていたんでしょうね。。。

本当に何でバイナリモードにしてなかったのか、自分でも信じられない。。
穴があったら入りたいです。。

タイトルとか全然関係ないタイトルだしw恥ずかしくてしょうがないw

softyaさん、私の完全な凡ミスに付き合せてしまったようで、本当に申し訳ございませんでした。
メモリのことについてはお勉強になりました。ありがとうございました。

kimuchiさん、本当に助かりました!
たぶん指摘していただけなかったら、ずっと気づかなかったとおもいますw

色々とググってたのがバカみたいです。。。
もっと視野を広く持たなきゃだめですね!

皆さんご迷惑をおかけ致しまして、申し訳ございませんでした。
本当にありがとうございました。これからもよろしくお願い致します!
oui C'est la Vie♪

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: BYTE型からsigned short型への正しい変換

#15

投稿記事 by softya(ソフト屋) » 9年前

すいません、昨日は風邪でだうんしてました。
無事解決して良かったです。

気をつけるとしたら、バイナリエディタでみるとかWAVファイルの波形を可視化するツールで一度チェックしていれば気づいたかも知れませんね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Ciel
記事: 252
登録日時: 9年前

Re: BYTE型からsigned short型への正しい変換

#16

投稿記事 by Ciel » 9年前

>>softyaさん

そうですね。波形を見たら気づいたかもしれませんね。
今後同じようなことがあったら一回波形見てみますね。ありがとうございました。
oui C'est la Vie♪

閉鎖

“C言語何でも質問掲示板” へ戻る